java中斷機制實例講解

一、導言

線程A對線程B發出建議: 你好,可以停止瞭喲~

在實際生產環境中,對於阻塞任務,可能存在一些情況導致阻塞任務取消、終止,例如: 計時器到期,I/O 完成,或者另一個線程的動作(釋放一個鎖,設置一個標志,或者將一個任務放在一個工作隊列中)。這種情況下可以使用java的中斷機制來進行線程間通信。

java線程中斷的實現是基於一個稱為中斷狀態的內部標志位來實現的,其中斷的含義更像是建議,一個線程如何響應另一個線程的中斷完全取決於程序員: 繼續向上拋出、封裝後拋出、中斷狀態復原、忽略等。java庫中的許多拋出 InterruptedException 的方法(例如 sleep)都被設計為取消當前操作並在接收到中斷時立即返回。

InterruptException異常就像是一個聲明,聲明拋出該異常的方法都可被中斷,比如wait、sleep、join。異常都是由可中斷方法自己拋出來的,並不是直接由interrupt()方法直接引起的。一般來說,任何通過拋出一個 InterruptedException 來退出的方法都應該清除中斷狀態。

二、java 中斷api

interrupt()

interrupt()方法本質上就是通過調用java.lang.Thread#interrupt0設置中斷flag為true,如下代碼演示瞭該方法的使用: 另啟一個線程中斷瞭當前線程。

@Test
public void interruptSt() {
 Thread mainThread = Thread.currentThread();
 new Thread(/*將當前線程中斷*/mainThread::interrupt).start();
 try {
 //public static native void sleep(long millis) throws InterruptedException;
 Thread.sleep(1_000);
 } catch (InterruptedException e) {
 System.out.println("main 線程被中斷瞭");
 }
 /*
 * 輸出: main 線程被中斷瞭
 */
}

interrupted()和isInterrupted()

public boolean isInterrupted() {
 // 設置this線程的中斷flag,不會重置中斷flag為true
 return isInterrupted(false);
}
public /*靜態方法*/static boolean interrupted() {
 // 設置當前線程的中斷flag,重置中斷flag為true
 return currentThread().isInterrupted(true);
}


使用示例

@Test
public void test_Flag() {
 Thread currentThread = Thread.currentThread();
 currentThread.interrupt();
 System.out.println("當前線程狀態 =" + currentThread.isInterrupted());
 System.out.println("當前線程狀態 =" + Thread.interrupted());
 System.out.println("當前線程狀態 =" + Thread.interrupted());
 /* 輸出
 當前線程狀態 =true
 當前線程狀態 =true
 當前線程狀態 =false*/
}

三、如何響應中斷?

調用一個可中斷的阻塞方法時需要處理受檢異常InterruptException,一般來說最容易的方式就是繼續拋出InterruptException ,讓調用方決定對中斷事件作出什麼應對。但是對於一些不能在方法頭直接添加異常聲明的,可以catch出後再進行一些操作,例如使用Runnable時:

image-20210102214450199

一般來說當catch到中斷時,應該對中斷狀態進行還原: 調用Thread.currentThread().interrupt();,除非明確自己的操作不會丟失線程中斷的證據,從而剝奪瞭上層棧的代碼處理中斷的機會。

四、總結

對目標線程調用interrupt()方法可以請求中斷一個線程,目標線程通過檢測isInterrupted()標志獲取自身是否已中斷。如果目標線程處於阻塞狀態,該線程會捕獲到InterruptedException。一般來說不要catchInterruptException後不做處理(“生吞中斷”)。

五、參考文章

https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

處理 InterruptedException

JAVA多線程之中斷機制(如何處理中斷?)

中斷線程

JAVA多線程之中斷機制(如何處理中斷?)

Thread的中斷機制(interrupt)

到此這篇關於java中斷機制實例講解的文章就介紹到這瞭,更多相關java中斷機制內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: