java中線程中斷的實現(xiàn)示例
1、線程中斷 即 線程的取消/關閉的機制
Java中停止一個線程的主要機制是中斷,中斷并不是強迫終止一個線程,它是一種 協(xié)作機制 ,是給線程傳遞一個取消/關閉信號,由線程自身來決定如何以及何時退出。
停止線程,但這個方法被標記為了過時。 @Deprecated public final void stop() ========================= 返回對應線程的中斷標志位是否為true。 public boolean isInterrupted() 返回當前線程的中斷標志位是否為true,并清空中斷標志位。 public static boolean interrupted() 表示中斷對應的線程。 public void interrupt()
2、線程對中斷interrupt()的反應
2.1、RUNNABLE:線程在運行或具備運行條件只是在等待操作系統(tǒng)調度
舉個栗子:
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("線程t 執(zhí)行中...");
}
});
t.start();
Thread.sleep(1);
t.interrupt();
System.out.println("main exit");
}RUNNABLE狀態(tài)的線程t被interrupt()后,是否終止中斷線程由線程t自身代碼邏輯決定。
2.2、WAITING/TIMED_WAITING:線程在等待某個條件或超時
線程執(zhí)行如下方法會進入WAITING狀態(tài): public final void join() throws InterruptedException public final void wait() throws InterruptedException 線程執(zhí)行如下方法會進入TIMED_WAITING狀態(tài): public final native void wait(long timeout) throws InterruptedException public static native void sleep(long millis) throws InterruptedException public final synchronized void join(long millis) throws InterruptedException
舉個栗子:
public class ThreadInterrupt {
public static void main(String[] args) {
Thread t = new Thread(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Thread.interrupted() = " + Thread.interrupted());
//Thread.interrupted() = false
System.out.println("Thread.interrupted() = " + Thread.interrupted());
//Thread.interrupted() = false
}
});
t.start();
t.interrupt();
}
}捕獲到InterruptedException,通常表示希望結束該線程,線程大概有兩種處理方式:
向上傳遞該異常,這使得該方法也變成了一個可中斷的方法,需要調用者進行處理。
有些情況,不能向上傳遞異常,比如Thread的run方法,它的聲明是固定的,不能拋出任何受檢異常,這時,應該捕獲異常,進行合適的清理操作,清理后,一般應該調用Thread的interrupt方法設置中斷標志位,使得其他代碼有辦法知道它發(fā)生了中斷。
2.3、BLOCKED:線程在等待鎖,試圖進入同步塊
舉個栗子:
public class ThreadInterrupt {
private final static Object lockObj = new Object();
private static class MyBlockedThread extends Thread {
@Override
public void run() {
System.out.println("MyBlockedThread.run = " + Thread.currentThread().isInterrupted());
synchronized (lockObj) {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().isInterrupted());
}
}
System.out.println("exit");
}
}
public static void main(String[] args) throws InterruptedException {
synchronized (lockObj) {
MyBlockedThread myBlockedThread = new MyBlockedThread();
myBlockedThread.start();
Thread.sleep(3000);
myBlockedThread.interrupt();
myBlockedThread.join(); // join方法會等待線程執(zhí)行完后返回
}
}
}myBlockedThread.join();該行代碼放開注釋掉情況下:線程一直等待鎖 BLOCKED。
com.michael.ThreadInterrupt.MyBlockedThread.run = false
myBlockedThread.join();該行代碼注釋掉情況下:因為主線程不再等待線程myBlockedThread結束,釋放鎖lock后,線程myBlockedThread會獲得鎖,然后檢測到發(fā)生了中斷,然后程序退出。
com.michael.ThreadInterrupt.MyBlockedThread.run = false exit
2.4、NEW/TERMINATED:線程還未啟動或已結束
舉個栗子:
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
System.out.println("線程t 執(zhí)行...");
});
t.interrupt();
System.out.println("NEW = " + t.isInterrupted());
t.start();
Thread.sleep(100);
t.interrupt();
System.out.println("TERMINATE = " + t.isInterrupted());
}
============ 執(zhí)行結果 ============
NEW = false
線程t 執(zhí)行...
TERMINATE = false2.5、IO操作
如果線程在等待IO操作,尤其是網絡IO,則會有一些特殊的處理。
- 如果IO通道是可中斷的,即實現(xiàn)了
InterruptibleChannel接口,則線程的中斷標志位會被設置,同時線程會收到異常ClosedByInterruptException。 - 如果線程阻塞于
Selector調用,則線程的中斷標志位會被設置,同時阻塞的調用會立即返回。 InputStream的read調用,該操作是不可中斷的,如果流中沒有數(shù)據(jù),read會阻塞 (但線程狀態(tài)依然是RUNNABLE),且不響應interrupt(),與synchronized類似,調用interrupt()只會設置線程的中斷標志,而不會真正"中斷"。
3、關于中斷的經驗
Java中取消/關閉線程技術是中斷,但它是一種協(xié)作機制,不會強制終止線程。線程在不同狀態(tài)和IO操作時對中斷的反應有所不同。
作為線程的實現(xiàn)者:應該提供明確的取消/關閉方法,并用文檔描述清楚其行為。
作為線程的調用者:應該使用其取消/關閉方法,而不是貿然調用interrupt()方法。
到此這篇關于java中線程中斷的實現(xiàn)示例的文章就介紹到這了,更多相關java 線程中斷內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot通過JSON傳遞請求參數(shù)的實例詳解
這篇文章主要介紹了SpringBoot通過JSON傳遞請求參數(shù),示例介紹SpringMVC如何通過JSON格式傳遞入參,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-11-11
SpringBoot自定義maven-plugin插件整合asm代碼插樁
本文主要介紹了SpringBoot自定義maven-plugin插件整合asm代碼插樁,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
mybatis動態(tài)sql之Map參數(shù)的講解
今天小編就為大家分享一篇關于mybatis動態(tài)sql之Map參數(shù)的講解,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
package打包一個springcloud項目的某個微服務報錯問題
這篇文章主要介紹了package打包一個springcloud項目的某個微服務報錯問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07

