java執行緒取消與關閉
行為良好的軟體能很完善地處理失敗、關閉和取消等過程。
1、任務取消的原因:1、使用者請求取消;2、有時間的限制;3、應用程式事件;4、錯誤;5、關閉
(1)中斷:呼叫interrupt只是傳遞了請求中斷,並不意味著立即停止目標執行緒;
(2)中斷策略:規定執行緒如何解釋某個中斷請求
(3)響應中斷:1:傳遞異常;2:恢復中斷狀態;
(4)計時執行
(5)通過Future來實現取消
(6)處理不可中斷的阻塞(繼承Thread,改寫interrupt方法)
(7)採用newTaskFor來封裝非標準的取消(java6,通過定製任務的Future可以改變Future.cancel的行為)
2、停止基於執行緒的服務
(1)例子:日誌服務
方式:通過呼叫log方法將日誌訊息放入某個佇列中,並由其他執行緒來處理;
停止該服務的方式:通過原子方式來檢查關閉請求,並且有條件地遞增一個計數器來儲存提交資訊的權利
(2)關閉ExecutorService
關閉ExecutorService的方法:shutdown&shutdownNow;在複雜的程式中,通常會將ExecutorService封裝到某個更高級別的服務中,並且該服務能提供其自己的生命週期方法。
(3)毒丸物件
毒丸物件是指一個放在佇列上的物件,其含義是:當得到這個物件時,立即停止;
限制:只有在生產者和消費者的數量都已知的情況下,才可以使用;生產者和消費者數目較大時,這種方法變得難以使用。
(4)例子:只執行一次的服務
場景:某個方法需要處理一批任務,並且當所有任務都處理完後才返回;
方式:通過一個私有的Executor來簡化服務的生命週期管理,其中該Executor的生命週期是由這個方法控制的。
(5)shutdownNow的侷限性
當通過shutdownNow來強行關閉ExecutorService時,嘗試取消正在執行的任務,並返回所有已經提交但未開始的任務。但無法在關閉過程中知道正在執行任務的狀態。除非任務本身會執行某種檢查。
3、處理非正常的執行緒終止(未捕獲異常的處理)
在Thread API中提供了Uncaught-ExceptionHandler,它能檢測出某個執行緒由於未捕獲的異常而終結的情況;
要為執行緒池中的所有執行緒設定一個UncaughtExceptionHandler;
4、JVM關閉
正常關閉&強行關閉
(1)關閉鉤子(執行緒安全)
在正常關閉總,JVM首先呼叫所有已註冊的關閉鉤子。關閉鉤子是指通過Runtime.addShutdownHook註冊的但尚未開始的執行緒。
關閉鉤子可以用於實現服務或應用程式的清理工作,例如刪除臨時檔案或消除無法由作業系統自動清除的資源。
(2)守護執行緒---JAVA中最典型的這種型別代表就是垃圾回收器。
守護執行緒:建立一個執行緒來執行一些輔助工作,又不希望這個執行緒阻礙jvm的關閉;
預設情況下,主執行緒建立的所有執行緒都是普通執行緒;
區別:僅在於當執行緒退出時發生的操作。當一個執行緒退出時,jvm會檢查其他症狀執行的執行緒,如果這些執行緒是守護執行緒,那麼JVM會正常退出操作。當jvm停止時,所有仍然存在的守護執行緒都會被拋棄。
(3)終結器(finalize)
終結器訪問的任何狀態都可能被多個執行緒訪問,這樣就必須對其訪問操作進行同步。所以終結器並不能保證他們將在任何時候呼叫會執行;
避免使用終結器;
(3)終結器