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

