比方說,我有一個線程池包含X
項目,並且給定的任務使用這些項目的Y
(其中Y
遠小於X
)。等待Java線程池中的線程子集
我想等待給定任務的所有線程(Y
項)完成,而不是整個線程池。
如果線程池的方法返回對聘用線程的引用,我可以簡單地將join()
分配給這些Y
線程中的每一個線程,但事實並非如此。
有沒有人知道一個優雅的方式來實現這一目標?謝謝。
比方說,我有一個線程池包含X
項目,並且給定的任務使用這些項目的Y
(其中Y
遠小於X
)。等待Java線程池中的線程子集
我想等待給定任務的所有線程(Y
項)完成,而不是整個線程池。
如果線程池的方法返回對聘用線程的引用,我可以簡單地將join()
分配給這些Y
線程中的每一個線程,但事實並非如此。
有沒有人知道一個優雅的方式來實現這一目標?謝謝。
而不是荷蘭國際集團Runnable
S,只是invokeAll()
一些Callable
秒 - 那麼你得到的每個上,您可以撥打get()
,該塊,直到任務完成了Future
。
您可以使用CyclicBarrier,並讓每個線程只在類型爲Y時等待。例如,
ExecutorService executor = Executors.newFixedThreadPool(X.size);
public void executeAllAndAwaitCompletion(List<? extends Y> myRunnableY){
final CyclicBarrier barrier = new CyclicBarrier(myRunnable.size()+1);
for(final Y y : myRunnableY){
executor.submit(new Runnable(){
public void run(){
y.run();//for the sake of this example y has a run method
barrier.await();
}
});
}
barrier.await();
}
因此,每個運行Y類型的線程都將等待所有這些Y完成。請注意,您必須在屏障大小上加1以說明最初執行的線程也要等待。
另請注意:如果Michael Borgwardt的例子適合您,那將是最好的。但是,如果您需要線程池,對於運行Y的每個線程不運行任何其他非Y的線程,那麼我的解決方案將是您可以執行此操作的唯一方法。 Future.get()只會阻塞調用線程,並且當線程池完成Y的執行時,它會接收其他一些(可能是非Y)任務。
您應該使用一個CompletionService
這是完全用於此目的。
Executor
CompletionService
take
或poll
提交任務等待任務完成ExecutorCompletionService
你提交已完成您可以與其他人共享Executor,只需在頂部創建CompletionService
並將其用於您的特定任務。
創建CountDownLatch
與Y
作爲計數,並在Y
任務中做latch.countDown()
。最後latch.await()
將確保所有的Y
任務都完成。
這真的很酷 - 謝謝 - 但所有的任務是相同的類型(他們只屬於不同的父母)。 – 2011-01-08 18:37:51