Java 中的線程中斷應用場景詳解
1、什么是線程中斷
Java線程中斷是一種線程間協(xié)作機制,用于通知線程應在合適的時候停止當前任務。中斷并非強制終止線程,而是通過設(shè)置線程的中斷標志位,由線程自身檢查并決定如何處理。
2、如何觸發(fā)線程中斷
- 使用
Thread.interrupt()方法- 該方法向目標線程發(fā)送中斷信號,設(shè)置其中斷標志位為true。若線程處于阻塞狀態(tài)(如wait()、sleep()),會拋出InterruptedException并清除中斷標志。
- 如果任務通過線程池submit()方法提交到線程池中執(zhí)行,可使用
Future.cancal(true)發(fā)送中斷信號
Future.cancal(true)會獲取到 阻塞在Future.get()的線程實例,然后調(diào)用thread.interrupt()方法。
3、如何處理線程中斷
3.1 線程中斷相關(guān)的核心方法
interrupt()- 向目標線程發(fā)送中斷信號,設(shè)置其中斷標志位為
true。若線程處于阻塞狀態(tài)(如wait()、sleep()),會拋出InterruptedException并清除中斷標志。
- 向目標線程發(fā)送中斷信號,設(shè)置其中斷標志位為
isInterrupted()- 檢查線程的中斷標志位狀態(tài),不會清除標志位。
Thread.interrupted()- 靜態(tài)方法,檢查當前線程的中斷狀態(tài)并清除標志位(即重置為
false)。
- 靜態(tài)方法,檢查當前線程的中斷狀態(tài)并清除標志位(即重置為
3.2 處理中斷的典型方式
響應中斷的阻塞操作
當線程調(diào)用如sleep()、wait()等方法時,需捕獲InterruptedException并恢復中斷狀態(tài)(避免吞沒中斷信號),因為 InterruptedException 會清除中斷狀態(tài):
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 重新設(shè)置中斷標志
// 執(zhí)行清理或退出邏輯
}主動檢查中斷狀態(tài)
通過循環(huán)中檢查isInterrupted()實現(xiàn)協(xié)作式終止:
while (!Thread.currentThread().isInterrupted()) {
// 執(zhí)行任務邏輯
}
3.3 注意事項
- 不可逆性:拋出
InterruptedException后中斷標志會被清除,需手動恢復。 - 非強制終止:線程可以忽略中斷,但通常不推薦。
- 資源清理:應在中斷處理中釋放資源(如關(guān)閉文件、網(wǎng)絡連接)。
4、線程中斷與線程終止的區(qū)別
- 線程中斷:是線程間協(xié)作機制,不強制終止線程的執(zhí)行,依賴線程自身響應。
- 強制終止(已廢棄的
stop()):直接終止線程,可能導致資源未釋放或數(shù)據(jù)不一致,不推薦使用。
5、線程中斷的應用場景
5.1 長時間運行任務的取消
當線程執(zhí)行耗時操作(如I/O阻塞、復雜計算)時,外部可通過中斷信號請求終止任務。例如:
Thread worker = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) { // 當收到中斷信號時退出循環(huán)
// 執(zhí)行任務邏輯
}
});
worker.start();
worker.interrupt(); // 發(fā)起中斷請求5.2 阻塞操作的快速響應
線程在Object.wait()、Thread.sleep()、或BlockingQueue.take()等阻塞方法時,調(diào)用interrupt()會拋出InterruptedException,立即終止等待狀態(tài):
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢復中斷狀態(tài)
// 清理資源
}5.3 服務或線程池的優(yōu)雅關(guān)閉
線程池通過中斷所有工作線程實現(xiàn)關(guān)閉。ExecutorService.shutdownNow()內(nèi)部會遍歷線程并調(diào)用interrupt(),任務需檢查中斷狀態(tài)主動退出。
5.4 超時控制
結(jié)合Future.cancel(true),可中斷正在執(zhí)行的異步任務。若任務未響應中斷,超時后仍可能繼續(xù)占用資源。
5.5 事件驅(qū)動架構(gòu)
在生產(chǎn)者-消費者模型中,中斷可用于緊急停止消費者線程。例如當系統(tǒng)內(nèi)存不足時,中斷日志寫入線程避免OOM。
6 線程中斷的常見問題
為什么發(fā)送線程中斷后我的線程還在執(zhí)行?
調(diào)用 interrupt 只是在線程中設(shè)置一個標記,并不會強制終止線程。如果線程執(zhí)行的代碼邏輯中沒有 Thread.currentThread().isInterrupted() 或 Thread.interrupted() 的檢測邏輯和退出語句則線程執(zhí)行不會受到任何影響。
為什么我無法檢測到線程中斷?
需要注意 拋出的 InterruptedException 異常和調(diào)用 Thread.interrupted() 會清除中斷狀態(tài),之后判斷線程的中斷狀態(tài)則是 false。正確的做法是使用 Thread.currentThread().interrupt(); 重新設(shè)置中斷狀態(tài),后續(xù)邏輯才能繼續(xù)判斷是否中斷。
到此這篇關(guān)于Java 中的線程中斷詳解的文章就介紹到這了,更多相關(guān)java線程中斷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JPA?通過Specification如何實現(xiàn)復雜查詢
這篇文章主要介紹了JPA?通過Specification如何實現(xiàn)復雜查詢,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
使用jdk1.8實現(xiàn)將list根據(jù)指定的值去分組的操作
這篇文章主要介紹了使用jdk1.8實現(xiàn)將list根據(jù)指定的值去分組的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Intellj Idea中的maven工程Java文件顏色不對,未被識別的解決
這篇文章主要介紹了Intellj Idea中的maven工程Java文件顏色不對,未被識別的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
SpringBoot集成JWT實現(xiàn)token驗證的流程
Json web token (JWT), 是為了在網(wǎng)絡應用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標準((RFC 7519).這篇文章主要介紹了SpringBoot集成JWT實現(xiàn)token驗證,需要的朋友可以參考下2020-01-01
Java實戰(zhàn)之用hutool-db實現(xiàn)多數(shù)據(jù)源配置
在微服務搭建中經(jīng)常會使用到多數(shù)據(jù)庫情形這個時候,下面這篇文章主要給大家介紹了關(guān)于Java實戰(zhàn)之用hutool-db實現(xiàn)多數(shù)據(jù)源配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2022-12-12
JAVA8獲取list集合中重復的元素與獲取去重數(shù)據(jù)實例
這篇文章主要給大家介紹了關(guān)于JAVA8獲取list集合中重復的元素與獲取去重數(shù)據(jù)的相關(guān)資料,在實際開發(fā)中經(jīng)常會遇到需要找出(刪除)一個list中某些元素的屬性相同的元素,需要的朋友可以參考下2023-07-07

