我完全不熟悉jsr166y庫,並且使用forkjoin庫編寫了一個例程,該庫分割了一個查詢並且同時運行它與數據庫副本。我在下面放了一個片段。 SelectTask擴展了RecursiveTask。Java ForkJoin Future似乎過早完成
ForkJoinExecutor fjPool;
Future queryResultsFut = null;
for (int i = 1; i <= lastBatchNum; i++) {
...
SelectTask selectMatchesRecursiveTask = new SelectMatchesTask(loadBalancer.getDao(), thisRuleBatch, queryResults);
queryResultsFut = fjPool.submit(selectMatchesRecursiveTask);
}
queryResultsFut.get();
的get方法的調用是爲了阻止父線程,直到所有查詢結果返回,這樣處理可以在彙總結果開始。
在CI環境中運行一段時間後,我發現現在並不總是這樣。當數據庫較慢時,即使任務仍在運行,線程也會繼續。這在我看來與我閱讀的文檔相矛盾。
也許我這樣做是錯誤的方式?我應該擴展ForkJoinTask而不是RecursiveTask嗎?
感謝您的啓發。您是否會知道執行程序框架是否包含將視爲「假設所有已完成」方面的內容,這些方面我都假設爲fork連接的設計目的? – barrymac 2011-03-10 11:38:03
其實它看起來像我應該使用Phaser來實現帶有ForkJoinPool的CyclicBarrier:http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/Phaser.html – barrymac 2011-03-10 11:50:08
不知道爲什麼你想要等待它們全部完成,但是'ExecutorService.invokeAll(Collection>)'返回'List >'的結果。當你遍歷它並獲得每個將來阻塞的結果,直到未來完成爲止,因此,在完成所有工作之前,不要完成迭代。如果你想以完成順序得到結果,你可以使用'CompletionService'。 –
2011-03-10 23:00:43