[英]Use case for Future.cancel(false)?
在什么情況下,想要將mayInterruptIfRunning
參數的false
傳遞給Future.cancel()
?
如果我理解正確,如果您傳遞false
並且任務被取消但線程沒有被中斷,則結果(或ExecutionException
)將永遠不可訪問,因為任務仍被標記為已取消(即isCancelled()
返回true
並且get()
拋出CancellationException
。)
其他可能的情況是:
Runnable
或Callable
實現不檢查中斷,即使你中斷它也會運行完成(這里中斷沒有區別) cancel()
之前,任務已經完成(再次中斷沒有區別) try ... finally
為此。) cancel
) 那么什么時候/為什么你會在不打斷任務的情況下取消任務?
TL;博士; Future.cancel(false)
僅用於避免啟動尚未啟動的任務。
有關並發和取消的兩個重要事項需要了解。
首先是在Java中取消純粹是合作的。 Java通過阻塞方法拋出InterruptedExcetions並在Thread上設置一個標志來發出取消請求的信號。 任務實現負責注意取消請求並取消自身。 Brian Goetz解釋了他在處理InterruptedException的帖子中的中斷 。 並非所有任務實現都能正確處理中斷。
要指出的第二件事是Future對象是一個占位符,用於將來要執行的任務的結果。 如果你沒有很多線程在運行,那么任務可能會立即開始執行,但也可能是所有線程都已被使用而且任務必須等待。 僅僅因為您對Future對象的引用並不意味着相應的任務實際上已經開始運行。 這有點像預訂。
您有一個Future對象,但該任務可能處於以下狀態之一:
如果您的任務處於第一個狀態“Waiting”,那么Future.cancel(true)
和Future.cancel(false)
都會將未來標記為已取消。 任務保留在要執行的任務隊列中,但是當執行程序到達任務時,它會注意到已取消的標志並跳過它。
如果您的任務處於第三個狀態“已完成”,則Future.cancel(true)
和Future.cancel(false)
返回false並且不執行任何操作。 這是有道理的,因為它們已經完成,並且沒有辦法撤消它們。
只有當您的任務處於第二個狀態“正在運行”時, mayInterruptIfRunning
標志才有用。
如果您的任務正在運行且mayInterruptIfRunning
為false,則執行程序不會執行任何操作並允許任務完成。
如果您的任務正在運行並且mayInterruptIfRunning
為true,則執行程序將中斷該任務。 但請記住關於合作取消的一點 - 為了中斷工作,必須實施任務來處理取消。
摘要:
Future.cancel(true)
適用於:
Future.cancel(false)
是正確的:
我有一個可能對您感興趣的用例:我有一個執行一組計划任務的線程。 其中一項任務可以由其自身或其他任務重新安排。
為此,我在隊列中的現有副本上使用Future.cancel(false)
,然后為新時間安排任務。
如果從計划任務本身調用此代碼,則取消操作將是無操作,並且該任務將被安排在將來再次運行。 如果從另一個上下文調用代碼,則即將執行的任務尚未開始執行,因此它將被取消,並替換為為新時間安排的任務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.