簡體   English   中英

Future.cancel的用例(false)?

[英]Use case for Future.cancel(false)?

在什么情況下,想要將mayInterruptIfRunning參數的false傳遞給Future.cancel()

如果我理解正確,如果您傳遞false並且任務被取消但線程沒有被中斷,則結果(或ExecutionException )將永遠不可訪問,因為任務仍被標記為已取消(即isCancelled()返回true並且get()拋出CancellationException 。)

其他可能的情況是:

  • RunnableCallable實現不檢查中斷,即使你中斷它也會運行完成(這里中斷沒有區別)
  • 在調用cancel()之前,任務已經完成(再次中斷沒有區別)
  • 任務需要在退出之前執行一些清理(一個編寫良好的實現將使用try ... finally為此。)
  • 任務無法立即終止,必須繼續執行受中斷影響的操作,例如阻塞I / O(在這種情況下,您可能根本不應該cancel

那么什么時候/為什么你會在不打斷任務的情況下取消任務?

TL;博士; Future.cancel(false)僅用於避免啟動尚未啟動的任務。

有關並發和取消的兩個重要事項需要了解。

首先是在Java中取消純粹是合作的。 Java通過阻塞方法拋出InterruptedExcetions並在Thread上設置一個標志來發出取消請求的信號。 任務實現負責注意取消請求並取消自身。 Brian Goetz解釋了他在處理InterruptedException的帖子中的中斷 並非所有任務實現都能正確處理中斷。

要指出的第二件事是Future對象是一個占位符,用於將來要執行的任務的結果。 如果你沒有很多線程在運行,那么任務可能會立即開始執行,但也可能是所有線程都已被使用而且任務必須等待。 僅僅因為您對Future對象的引用並不意味着相應的任務實際上已經開始運行。 這有點像預訂。

您有一個Future對象,但該任務可能處於以下狀態之一:

  1. 等候。 例如,它可能在等待處理器時間的其他任務的隊列中。
  2. 運行。
  3. 已完成。

如果您的任務處於第一個狀態“Waiting”,那么Future.cancel(true)Future.cancel(false)都會將未來標記為已取消。 任務保留在要執行的任務隊列中,但是當執行程序到達任務時,它會注意到已取消的標志並跳過它。

如果您的任務處於第三個狀態“已完成”,則Future.cancel(true)Future.cancel(false)返回false並且不執行任何操作。 這是有道理的,因為它們已經完成,並且沒有辦法撤消它們。

只有當您的任務處於第二個狀態“正在運行”時, mayInterruptIfRunning標志才有用。

如果您的任務正在運行且mayInterruptIfRunning為false,則執行程序不會執行任何操作並允許任務完成。

如果您的任務正在運行並且mayInterruptIfRunning為true,則執行程序將中斷該任務。 但請記住關於合作取消的一點 - 為了中斷工作,必須實施任務來處理取消。

摘要:

Future.cancel(true)適用於:

  1. Future代表了一個長期運行的任務,已知它已經被實現來處理中斷。

Future.cancel(false)是正確的:

  1. 任務實現無法處理被中斷。
  2. 如果任務實現支持取消,它是未知的。
  3. 您願意等待已經開始的任務完成。

如果您害怕中斷任務的執行可能會使事情處於不良狀態,並且您只是想將其標記為已取消,以便Future用戶將意識到它(例如,他們應該知道請求的統計信息未執行時間)。

編寫正確處理中斷的線程代碼根本不是微不足道的,因此人們可能更願意避免它。

有些信息可以發現在這里在這里 ,當然在大書用Java並發編程 (由誰最初寫的家伙java.util.concurrent )。

我有一個可能對您感興趣的用例:我有一個執行一組計划任務的線程。 其中一項任務可以由其自身或其他任務重新安排。

為此,我在隊列中的現有副本上使用Future.cancel(false) ,然后為新時間安排任務。

如果從計划任務本身調用此代碼,則取消操作將是無操作,並且該任務將被安排在將來再次運行。 如果從另一個上下文調用代碼,則即將執行的任務尚未開始執行,因此它將被取消,並替換為為新時間安排的任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM