1. 程式人生 > >終止執行緒的2種方法。標記法和中斷

終止執行緒的2種方法。標記法和中斷

引言

在原來的jdk版本中:
提供了暫停,恢復,終止執行緒的方法,分別是suspend(),resume(),stop();
但是它們都存在缺陷,比如暫停suspend()方法在呼叫後,執行緒不會釋放資源(比如:鎖),而是佔有著資源進入睡眠狀態。stop()方法在呼叫後,通常不能保證執行緒的資源正常的釋放,因為他根本沒有給予執行緒釋放資源的機會。
正因為這些方法帶來的不良影響,使得它們被廢除。

替代

然而聰明的程式設計師還是想出來了替代上述api的方法,

原始api 替代方案
暫停和恢復 等待-通知機制
終止 標記法和中斷法

終止執行緒-法一:標記法

通過置標記為相反的布林值,來終止執行緒

程式碼:

package Interrupt;

public class InterruptThread4 {
    public static void main(String args[]) throws InterruptedException {
        ThreadTest t1=new ThreadTest();
        t1.start();
        Thread.sleep(1000);
        System.out.println(System.currentTimeMillis());
        t1.stopMe();

    }
    static
class ThreadTest extends Thread{ private boolean stopMe=false; public void stopMe() { this.stopMe = true; } @Override public void run() { while(true){ if(stopMe){ System.out.println("interrupt!"); break
; } try { System.out.println("t1 sleep"); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } Thread.yield(); } System.out.println(System.currentTimeMillis()); } } }

結果:

t1 sleep
1501152592588
interrupt!
1501152596589

現象:

通過列印的時間戳對比發現,發出中斷訊號和執行緒中斷相隔的時間為5s,這正是執行緒休眠的時間。所以通過標誌來中斷執行緒,假設執行緒中有sleep()和wait()方法,它達不到立即終止的作用,必須等執行緒恢復正常執行或者喚醒後才能終止。

終止執行緒-法二:中斷法

Thread中斷是通過內部的標記欄位來進行的,執行緒中斷並不是使執行緒立刻退出,而是傳送給執行緒一個通知,至於目標執行緒接到通知如何處理是由執行緒自己決定。這是和stop()方法強行退出是不同的

api

在演示例項之前,先來了解下Thread類中斷的api

api 含義
public void interrupt() 中斷執行緒
public boolean isInterrupt() 判斷執行緒是否中斷
public static boolean interrupted 判斷執行緒是否中斷,並且清除當前中斷狀態

程式碼

package Interrupt;

public class InterruptThread3 {
    public static void main(String args[]) throws InterruptedException {
        Thread t1=new Thread(){
            @Override
            public void run() {
                while(true){
                    if(Thread.currentThread().isInterrupted()){
                        System.out.println("interrupt!");
                        break;
                    }
                    try {
                        System.out.println("t1 sleep");
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        //設定中斷狀態
                        Thread.currentThread().interrupt();
                    }
                    Thread.yield();
                }
                System.out.println(System.currentTimeMillis());
            }
        };
        t1.start();
        Thread.sleep(1000);
        System.out.println(System.currentTimeMillis());
        t1.interrupt();
    }
}

結果

1501153532961
java.lang.InterruptedException: sleep interrupted
interrupt!
at java.lang.Thread.sleep(Native Method)
1501153532963
at Interrupt.InterruptThread3$1.run(InterruptThread3.java:15)

現象

發現interrupt()幾乎可以達到立即中斷的效果,但是執行緒必須捕獲InterruptedException異常這是前提條件。否則執行緒會永遠的執行下去。
至於在catch程式碼塊中為什麼要通過Thread.currentThread().interrupt();來重置中斷狀態,因為當jvm因為sleep(),wait()等需要捕獲異常的方法被中斷時,在丟擲InterruptedException之前,它會先清除掉執行緒的中斷標誌位,使得isInterrupted()返回false;

中斷的兩種方法對比

如果執行緒中有wait()和sleep()等方法,用中斷法來終止執行緒效果更好。
因為如果執行緒長久的等待下去,而沒有任何其他執行緒對其喚醒或者長期的睡眠下去,標誌法根本無法中斷,而中斷法可以立即中斷。

最後的兩點非常重要:

a.要使用interrupt()方法來中斷執行緒,一定要在方法裡捕獲InterruptedException。
b.如果因為wait(),或sleep()等需要捕獲InterruptedException的方法被中斷時,jvm會在丟擲異常之前先清除中斷標記位,使得isInterrupted()返回為false。素以我們要在判斷之前先重新設定好標記位

好久沒寫部落格了,閃~

相關推薦

終止執行2方法標記中斷

引言 在原來的jdk版本中: 提供了暫停,恢復,終止執行緒的方法,分別是suspend(),resume(),stop(); 但是它們都存在缺陷,比如暫停suspend()方法在呼叫後,執行緒不會釋放資源(比如:鎖),而是佔有著資源進入睡眠狀態。stop(

android 終止執行方法

其實android 不提倡我們終止執行緒的,以前的一些函式,stop等等都不推薦使用了,但是當我們確實要終止執行緒的時候,可看考下面的問題 有時當一個元件或者activity被destory()的時候要求其啟動的執行緒也一起終止掉,現在就來總結了一下有這有幾種方法:

將給定非負整數列表中的數字排列成最大數字的2方法例如,給定[50,2,1,9],最大數字為95021

一、題目簡介 編寫一個能將給定非負整數列表中的數字排列成最大數字的函式。例如,給定[50,2,1,9],最大數字為95021。 此處以如下陣列為例:Integer[] num=new Integer[]{51,9,370,82,4,796}; 二、例項程式碼 1、方法一: /

一、多執行基礎概念、實現執行方法中斷執行方法,以及執行狀態轉化

1、CPU核心數和執行緒數的關係 1:1的關係,引入超執行緒之後,就是1:2 2、cpu時間輪轉機制,即RR排程 3、程序和執行緒 程序:程式執行資源分配最小單位,程序內部有多個執行緒,多個執行緒之間會共享程序資源 執行緒:CPU排程的最小單位 4、並行和併發

執行實現區別-繼承Thread實現Runable

一  前面一種比較簡潔。後面一種更靈活,因為java可以實現多個介面,但是隻能繼承一個類 二  適合於資源的共享 如果不涉及 多執行緒直接資源共享用Thread 比較好,否則實現Runable較好 Thread其實也是實現了Runnable介面  Thread中的start(

終止執行的三方法

 有三種方法可以使終止執行緒。    1.  使用退出標誌,使執行緒正常退出,也就是當run方法完成後執行緒終止。    2.  使用stop方法強行終止執行緒(這個方法不推薦使用,因為stop和suspend、resume一樣,也可能發生不可預料的結果)。    3.  使

jmeter手動新增cookie及執行間cookie共享的2方法

只要有登入後的cookie內容(可能是session、可能是token),手動設定到cookie管理器中後,呼叫其他的非登入介面將不需要在登入了(除非當前的cookie失效——由session或token的失效時間確定,貌似session的預設失效時間是30分鐘)

Java終止執行的三方法

使用標誌位退出執行緒 使用stop方法強制終止執行緒 使用interrupt終止執行緒 1. 使用標誌位退出執行緒 這種也是最常用的方法,就是定義一個boolean型的標誌位,線上程的run方法中根據這個標誌位是true還是false來判斷是否退出,這種

終止執行方法(不看後悔,看了必懂)

在java語言中,可以使用stop()方法和suspend()方法來終止執行緒的執行. 當使用Thread.stop()來終止執行緒時,它會釋放已經鎖定的所有監視資源,具有不安全性 suspend()方法不會釋放鎖,容易發生死鎖(兩個或者兩個以上程序在執行過程中,因爭奪資源而造成程序間互

python多執行———2、建立多執行的兩方式

 法一、使用Thread類例項化 法二、繼承Thread來實現多執行緒 #對於io操作來說,多執行緒和多程序效能差別不大 #1、使用Thread類例項化 import time import threading def get_detail_html(url): prin

2018-11-28親測有效的python執行終結,終止執行方法

import ctypes def _async_raise(tid, exctype): """raises the exception, performs cleanup if needed""" if not inspect.isclass(exctype):

執行2】Thread的方法

Thread的常用方法 (1).start():啟動執行緒並執行相應的run()方法 (2).run():子執行緒要執行的程式碼放入run()方法中 (3).currentThread():靜態的,調取當前的執行緒 (4).getName():獲取此執行緒的名字 (

JAVA中執行同步的方法(7)彙總

同步的方法: 一、同步方法   即有synchronized關鍵字修飾的方法。 由於java的每個物件都有一個內建鎖,當用此關鍵字修飾方法時, 內建鎖會保護整個方法。在呼叫該方法前,需要獲得內建鎖,否則就處於阻塞狀態。 注: synchronized關鍵字也可以修飾靜態

java執行學習(二): 終止執行講解:Stop()方法(後附如何正確終止執行)

本章來學習Java的stop執行緒終止方法; 老規矩,先看原始碼: @Deprecated public final void stop() { SecurityManager var1 = System.getSecurityManager(); if (var1 != n

使用QThread執行的新方法 moveToThread

工作中使用QT開發遇到使用多執行緒,對於執行緒的建立,研究後發現有些疑惑。各執一詞先上兩個連結:     QThread似乎是很難的一個東西,特別是訊號和槽,有非常多的人(儘管使用者本人往往不知道)在用不恰當(甚至錯誤)的方式在使用QThread,隨便用goog

Java多執行3實現方法

Java中的多執行緒有三種實現方式:1.繼承Thread類,重寫run方法。Thread本質上也是一個實現了Runnable的例項,他代表一個執行緒的例項,並且啟動執行緒的唯一方法就是通過Thread類的start方法。2.實現Runnable介面,並實現該介面的run()

執行(2)--匿名內部類實現執行的兩方式

package com.fenqing.duoxiancheng; public class d3_thread { public static void main(String[] arg

執行中的方法、兩實現方式、匿名內部類建立多執行執行安全問題的解決、

多執行緒兩種實現方式: 方式一: 繼承Thread類的方式 方式二: 實現Runnable介面的方式。 方式一: 步驟: // 1. 定義一個類,然後繼承Thread //

1.如何避免野指標2.獲取字串的兩方法以及malloc,calloc,ralloc的使用注意點3.二維三維陣列4.陣列函式的區別

一:野指標: char *ptr; 定一個指標,沒有賦值,用NULL。 char *ptr = NULL 即表示指向空,不能再做賦值,不能對0地址操作訪問。 //#define NULL (void *)o 如果出現段錯誤,看看對NULL有沒有賦值。 如何避免野指標而不

三個執行T1,T2,T3.保證順序執行的三方法

Thread t1 = new Thread(new Runnable() { public void run() { try { Thread.sleep(100