若是外部代碼能在某個操做正常完成以前將其置入「完成」狀態,那麼這麼操做就能夠稱爲可取消的。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有一個cancel(boolean mayInterruptIfRunning) 方法:該方法是非阻塞的,該方法能夠用來(嘗試)終止一個任務。get
cancel(false) 與 cancel(true)的區別在於,cancel(false)只取消已經提交但尚未被運行的任務(即任務就不會被安排運行);而 cancel(true) 會取消全部已經提交的任務,包括正在等待的和正在運行的任務。it