福禍由天不由我,我命由我不由天,
一、導言
執行緒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()
在說這兩個方法之前先說下private native boolean isInterrupted(boolean ClearInterrupted)這個方法,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時:
一般來說當catch到中斷時,應該對中斷狀態進行還原: 呼叫Thread.currentThread().interrupt();,除非明確自己的操作不會丟失執行緒中斷的證據,從而剝奪了上層堆疊的代碼處理中斷的機會,
四、總結
- 對目標執行緒呼叫
interrupt()方法可以請求中斷一個執行緒,目標執行緒通過檢測isInterrupted()標志獲取自身是否已中斷,如果目標執行緒處于阻塞狀態,該執行緒會捕獲到InterruptedException, - 一般來說不要catch
InterruptException后不做處理(“生吞中斷”),
五、參考文章
- https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
- 處理 InterruptedException
- JAVA多執行緒之中斷機制(如何處理中斷?)
- 中斷執行緒
- JAVA多執行緒之中斷機制(如何處理中斷?)
- Thread的中斷機制(interrupt)
- <<java并發編程實戰>>

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/243823.html
標籤:java
上一篇:B-Tree洗掉、下溢修復、插入、上溢修復Java源代碼及注釋
下一篇:JVM快速入門(上)
