Java 停止線程需要注意的地方
Java中停止線程的原則是什么?
在 Java 中, 最好的停止線程的方式是使用中斷 interrupt, 但是這僅僅是會通知到被終止的線程 "你該停止運行了", 被終止的線程自身擁有決定權(quán) (決定是否、以及何時停止), 這依賴于請求停止方和被停止方都遵守一種約定好的編碼規(guī)范.
- 任務(wù)和線程的啟動很容易. 在大多數(shù)時候, 我們都會讓它們運行直到結(jié)束, 或者讓它們自行停止.然而, 有時候我們希望提前結(jié)束任務(wù)或線程, 或許是因為用戶取消了操作,或者服務(wù)需要被快速關(guān)閉, 或者是運行超時或出錯了.
- 要使任務(wù)和線程能安全、快速、可靠地停止下來, 并不是一件容易的事. Java沒有提供任何機制來安全地終止線程. 但它提供了中斷 (Interruption), 這是一種協(xié)作機制,能夠使一個線程終止另一個線程的當(dāng)前工作.
- 這種協(xié)作式的方法是必要的, 我們很少希望某個任務(wù)、線程或服務(wù)立即停止,因為這種立即停止會使共享的數(shù)據(jù)結(jié)構(gòu)處于不一致的狀態(tài). 相反, 在編寫任務(wù)和服務(wù)時可以使用一種協(xié)作的方式: 當(dāng)需要停止時,它們首先會清除當(dāng)前正在執(zhí)行的工作, 然后再結(jié)束. 這提供了更好的靈活性, 因為任務(wù)本身的代碼比發(fā)出取消請求的代碼更清楚如何執(zhí)行清除工作.
- 生命周期結(jié)束 (End-of-Lifecycle) 的問題會使任務(wù)、服務(wù)以及程序的設(shè)計和實現(xiàn)等過程變得復(fù)雜, 而這個在程序設(shè)計中非常重要的要素卻經(jīng)常被忽略. 一個在行為良好的軟件與勉強運的軟件之間的最主要區(qū)別就是, 行為良好的軟件能很完善地處理失敗、關(guān)閉和取消等過程.
處理中斷的最好方法是什么?
優(yōu)先選擇在方法上拋出異常.
用 throws InterruptedException 標(biāo)記你的方法, 不采用 try 語句塊捕獲異常,以便于該異??梢詡鬟f到頂層, 讓run方法可以捕獲這一異常, 例如:
void subTask() throws InterruptedException sleep(delay); }
由于 run 方法內(nèi)無法拋出 checked Exception (只能用 try catch), 頂層方法必須處理該異常, 避免了漏掉或者被吞掉的情況, 增強了代碼的健壯性.
如果不能拋出中斷, 要怎么做?
如果不想或無法傳遞 InterruptedException (例如用 run 方法的時候, 就不讓該方法 throws InterruptedException), 那么應(yīng)該選擇在 catch 子句中調(diào)用 Thread.currentThread().interrupt() 來恢復(fù)設(shè)置中斷狀態(tài), 以便于在后續(xù)的執(zhí)行依然能夠檢查到剛才發(fā)生了中斷.
代碼演示詳見視頻, 在這里, 線程在sleep期間被中斷, 并且由 catch 捕獲到該中斷, 并重新設(shè)置了中斷狀態(tài), 以便于可以在下一個循環(huán)的時候檢測到中斷狀態(tài), 正常退出.
為什么用 volatile 停止線程不夠全面?
解答: 這種做法是錯誤的, 或者說是不夠全面的, 在某些情況下雖然可用, 但是某些情況下有嚴(yán)重問題。
這種方法在《Java并發(fā)編程實戰(zhàn)》中被明確指出了缺陷, 我們一起來看看缺陷在哪里:
此方法錯誤的原因在于, 如果我們遇到了線程長時間阻塞 (這是一種很常見的情況, 例如生產(chǎn)者消費者模式中就存在這樣的情況), 就沒辦法及時喚醒它, 或者永遠都無法喚醒該線程, 而 interrupt 設(shè)計之初就是把 wait 等長期阻塞作為一種特殊情況考慮在內(nèi)了, 我們應(yīng)該用 interrupt 思維來停止線程.
以上就是Java 停止線程需要注意的地方的詳細內(nèi)容,更多關(guān)于Java 停止線程的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot 3.0 新特性內(nèi)置聲明式HTTP客戶端實例詳解
聲明式 http 客戶端主旨是使得編寫 java http 客戶端更容易,為了貫徹這個理念,采用了通過處理注解來自動生成請求的方式,本文給大家詳解介紹SpringBoot 聲明式HTTP客戶端相關(guān)知識,感興趣的朋友跟隨小編一起看看吧2022-12-12
IDEA 2020.2 +Gradle 6.6.1 + Spring Boot 2.3.4 創(chuàng)建多模塊項目的超詳細教程
這篇文章主要介紹了IDEA 2020.2 +Gradle 6.6.1 + Spring Boot 2.3.4 創(chuàng)建多模塊項目的教程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
數(shù)組實現(xiàn)Java 自定義Queue隊列及應(yīng)用操作
這篇文章主要介紹了數(shù)組實現(xiàn)Java 自定義Queue隊列及應(yīng)用操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
RabbitMQ 的消息持久化與 Spring AMQP 的實現(xiàn)詳解
這篇文章主要介紹了RabbitMQ 的消息持久化與 Spring AMQP 的實現(xiàn)剖析詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-08-08
Mybatis-plus通過添加攔截器實現(xiàn)簡單數(shù)據(jù)權(quán)限
系統(tǒng)需要根據(jù)用戶所屬的公司,來做一下數(shù)據(jù)權(quán)限控制,具體一點,就是通過表中的company_id進行權(quán)限控制,項目使用的是mybatis-plus,所以通過添加攔截器的方式,修改查詢sql,實現(xiàn)數(shù)據(jù)權(quán)限,本文就通過代碼給大家詳細的講解一下,需要的朋友可以參考下2023-08-08

