2015-06-18 24 views
0

我對Future的用法有一些疑問。在處理我的查詢之前,請通過下面的示例。關於Java Future和RejectionHandler的查詢

http://javarevisited.blogspot.in/2015/01/how-to-use-future-and-futuretask-in-Java.html

  1. 使用線程池& Executors的主要目的是爲了不阻塞主線程異步執行任務。但是,一旦您使用Future,它會阻止調用線程。我們是否必須創建單獨的新線程/線程池來分析Callable任務的結果? OR還有其他什麼好的解決方案嗎?
  2. 由於Future呼叫阻止了呼叫者,是否值得使用此功能?如果我想分析任務的結果,我可以進行同步呼叫,並檢查呼叫的結果,而不需要Future
  3. 使用RejectionHandler處理拒絕任務的最佳方式是什麼?如果任務被拒絕,將任務提交給另一個線程或線程池還是將同一任務再次提交到當前的ThreadPoolExecutor是好習慣?

如果我的思維過程對此功能有誤,請糾正我。

+1

期貨做*不*阻止調用線程。猜猜爲什麼在你鏈接的代碼示例中有一個*循環*?因爲'isDone'不*等待。雖然循環中的代碼示例輪詢isDone仍然是不好的編碼風格。如果你想等待,你可以使用'get',並且如果你不想讓調用者線程被阻塞,你可以[指定超時](http://docs.oracle.com/javase/8/docs/ api/java/util/concurrent/Future.html#get-long-java.util.concurrent.TimeUnit-) – Holger

+1

查看[RejectedExecutionHandler',「All Known Implementing Classes」的文檔](http:// docs。 oracle.com/javase/8/docs/api/java/util/concurrent/RejectedExecutionHandler.html)以獲取處理策略的建議。 – Holger

+0

有沒有來自Future的API在結果可用時得到通知,因爲超時並未完全達到目的?如果不可用,最好不要在調用者線程本身中同步使用Future並執行任務? –

回答

1

您的問題是關於在異步操作完成時執行操作。 Future另一方面,如果您有異步操作正在運行時可以執行的不相關的活動,那麼它是很好的。然後,您可以通過isDone()定期輪詢Future所代表的動作,如果不是,則可以執行其他操作,或者在您的當前線程沒有更多不相關的工作時調用阻止get()

如果您想要在不阻止當前線程的情況下安排完成操作,則可以改爲使用CompletableFuture來提供此類功能。

0

CompletableFuture是查詢1和2的解決方案通過@的建議霍爾格

我想更新關於查詢有關RejectedExecutionHandler機制3.

Java提供了四種類型的拒絕處理程序的政策按javadocs

  1. 在默認ThreadPoolExecutor.AbortPolicy,處理程序拒絕時拋出一個運行時RejectedExecutionException

  2. ThreadPoolExecutor.CallerRunsPolicy中,調用自身執行的線程運行該任務。這提供了一個簡單的反饋控制機制,可以減慢提交新任務的速度。

  3. ThreadPoolExecutor.DiscardPolicy中,無法執行的任務將被簡單地刪除。

  4. ThreadPoolExecutor.DiscardOldestPolicy中,如果執行程序沒有關閉,工作隊列頭部的任務將被丟棄,然後重試執行(可能會再次失敗,導致重複執行)。)

CallerRunsPolicy:如果您在任務隊列中更多的任務,使用此策略會降低性能。你必須小心,因爲拒絕任務將由主線程自己執行。如果運行拒絕的任務對您的應用程序至關重要,並且您的任務隊列有限,則可以使用此策略。

DiscardPolicy:如果丟棄非關鍵事件不會打擾您,那麼您可以使用此策略。

DiscardOldestPolicy:丟棄舊的工作,並嘗試恢復的最後一個

如果他們都不適合你的需要,你可以實現自己的RejectionHandler