您現在的位置是:首頁 > 音樂首頁音樂

如何正確的中斷執行緒?你的姿勢是否正確

由 程式那點事 發表于 音樂2022-12-22
簡介Sleep是否會收到執行緒中斷訊號public class _24_ThreadTest implements Runnable {@Overridepublic void run() {int count =

中斷程式沒有退出之前一直執行嗎

Java停止執行緒的邏輯(協同、通知)

在Java程式中,我們想要停止一個執行緒可以透過interrupt方法進行停止。但是當我們呼叫interrupt方法之後,它可能並不會立刻就會停止執行緒,而是通知執行緒需要停止。執行緒接收到通知之後會根據自身的情況判斷是否需要停止,它可能會立即停止,也有可能會執行一段時間後停止,也可能根本就不停止。

那麼Java為什麼要選擇這種非強制性的執行緒中斷呢?其實更多是為了資料安全,保證程式的健壯性。因為我們不知道程式正在做什麼事情。如果貿然停止,可能會造成資料的錯亂、不完整。

如何正確的中斷執行緒?你的姿勢是否正確

一個簡單的例子

public class _24_ThreadTest implements Runnable { @Override public void run() { int count = 0; while (!Thread。currentThread()。isInterrupted() && count <= 2000) { System。out。println(“count: ” + count++); } } public static void main(String[] args) throws Exception { _24_ThreadTest threadTest = new _24_ThreadTest(); Thread thread = new Thread(threadTest); thread。start(); Thread。sleep(10); // 中斷執行緒 thread。interrupt(); }}

這個例子是一個簡單的透過interrupt中斷執行緒的案例,run方法中透過判斷當前執行緒是否中斷,並且count是否大於2000來進行迴圈。如果執行緒中斷則退出迴圈,執行緒執行結束。這種就屬於執行緒正常停止的情況。

Sleep是否會收到執行緒中斷訊號

public class _24_ThreadTest implements Runnable { @Override public void run() { int count = 0; while (!Thread。currentThread()。isInterrupted() && count <= 2000) { try { System。out。println(“count: ” + count++); // 子執行緒睡眠 Thread。sleep(1000 * 2); System。out。println(“方法體:” + Thread。currentThread()。isInterrupted()); } catch (InterruptedException e) { System。out。println(“異常:” + Thread。currentThread()。isInterrupted()); // 執行緒中斷標誌位被重置為false e。printStackTrace(); } } } public static void main(String[] args) throws Exception { _24_ThreadTest threadTest = new _24_ThreadTest(); Thread thread = new Thread(threadTest); thread。start(); Thread。sleep(10); // 中斷執行緒 thread。interrupt(); }}

如果在子執行緒中睡眠中,主執行緒透過interrupt方法進行中斷,那麼子執行緒還能不能收到中斷訊號。其實在這種情況下執行緒也是可以接收到訊號通知的,這個時候會丟擲InterruptedException,並且將執行緒中斷標誌位設定為false。

在丟擲異常後,執行緒標誌位被設定為false,那麼在下次迴圈判斷count沒有為false的情況下,還是可以進入迴圈體的。這個時候執行緒就無法停止。

執行結果:

如何正確的中斷執行緒?你的姿勢是否正確

案例場景

在進行一些後臺任務透過執行緒跑的時候,如果在迴圈中遇到執行緒中斷異常,我們需要終止當前任務,並且告訴客戶端當前任務執行失敗的是哪條記錄,這種情況下就可以透過異常中再次中斷的方式來停止執行緒,並且可以返回給客戶端當前出現異常的記錄是哪條。而不會是接著執行下去。

解決方法

如何正確的中斷執行緒?你的姿勢是否正確

既然我們已經知道,在出現執行緒中斷異常之後執行緒中斷標誌位會被重置為false,那麼我們可以在異常中手動的再次中斷當前執行緒,那麼就可以完全停止執行緒任務。

總結

上面我們簡單介紹瞭如何正確的停止執行緒,如果在以後的面試中被問到這類問題,那麼你是不是可以流暢的回答面試官了。

在run方法中遇到異常,我們是不能直接生吞的,一定要做處理,你可以是簡單的日誌記錄,也可以中斷執行緒。但就是不能不做任何處理。

其實還有其他的一些方法來停止執行緒,比如stop(),這類方法已被捨棄,這種強制停止可能會引起執行緒的資料安全問題,所以已經不再推薦使用了。