Java併發編程實戰筆記5:取消與關閉

任務取消

若是外部代碼能在某個操做正常完成以前將其置入「完成」狀態,那麼這麼操做就能夠稱爲可取消的。Java中有一些協做式的機制,使得請求取消的任務和代碼都遵循一種協商好的協議。編程

線程中斷是一種用於中止線程的協做機制,線程能夠經過這種機制來通知另外一個線程,告訴它在合適的或者可能的狀況下中止當前工做。併發

每一個線程都有一個布爾變量表示其中斷狀態。使用interrupt()方法將中斷狀態設置爲ture;使用isInterrupted()判斷線程的中斷狀態;使用Thread.interrupted()判斷當前線程的中斷狀態,並將當前線程的中斷狀態設置爲false。函數

調用interrupt()方法並不意味着當即中止目標線程正在進行的工做,而只是傳遞了請求中斷的消息,而後由線程在合適的時刻中斷本身。一般,中斷是實現取消的最合理的方式。.net

當檢查到中斷請求後,任務並不須要放棄全部的操做,它能夠推遲處理中斷請求,並直到某個更合適的時候。所以須要記住中斷請求,並在完成當前任務後拋出InterruptedException或者表示已經收到中斷請求。線程

響應中斷

當調用可中斷的阻塞函數時,如Thread.sleep()或者BlokcingQueue.put(),Object.wait()等。能夠在別的線程中調用當前線程對象的interrupt方法觸發這些函數拋出InterruptedException異常,有兩種策略來處理:對象

  • 傳遞異常,從而使你的方法也成爲可中斷的阻塞方法
  • 恢復中斷狀態,從而使調用棧中的上層代碼可以對其進行處理。

當你捕獲到InterruptedException異常後,當前線程的中斷狀態已經被修改成false(表示線程未被中斷);此時你若可以處理中斷,則不用理會該值;但若是你繼續向上拋InterruptedException異常,你須要再次調用interrupt方法,將當前線程的中斷狀態設爲true。blog

只有實現了線程中斷策略的代碼才能屏蔽中斷請求,不能捕獲異常卻不作處理。ci

使用Future實現取消

Future有一個cancel(boolean mayInterruptIfRunning) 方法:該方法是非阻塞的,該方法能夠用來(嘗試)終止一個任務。get

  • 若是任務運行以前調用了該方法,那麼任務就不會被運行;
  • 若是任務已經完成或者已經被取消,那麼該方法方法不起做用;
  • 若是任務正在運行,而且 cancel 傳入參數爲 true,那麼便會去終止與 Future 關聯的任務。

cancel(false) 與 cancel(true)的區別在於,cancel(false)只取消已經提交但尚未被運行的任務(即任務就不會被安排運行);而 cancel(true) 會取消全部已經提交的任務,包括正在等待的和正在運行的任務。it

參考資料

相關文章
相關標籤/搜索