Let's say I have a thread pool containing X
items, and a given task employs Y
of these items (where Y
is much smaller than X
).
I wa开发者_开发技巧nt to wait for all of the threads of a given task (Y
items) to finish, not the entire thread pool.
If the thread pool's execute()
method returned a reference to the employed thread I could simply join()
to each of these Y
threads, but it doesn't.
Does anyone know of an elegant way to accomplish this? Thanks.
You can use a CyclicBarrier and have each thread wait only when it is of type Y. For example.
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();
}
So each thread that is running type Y will wait until all those Y's have completed. Note you have to add 1 to the barrier size to account for the initially executing thread to wait also.
Also Note: If Michael Borgwardt's example works for you that would be best. However, if you need the thread pool, for each thread that is running Y to not run any other non-Y's then my solution would be the only way you can do it. Future.get() will only block the calling thread, and when the thread pool finishes Y's execution it will then pick up some other (possibly non-Y) task.
Instead of execute()
ing Runnable
s, just invokeAll()
some Callable
s - then you get a Future
for each on which you can call get()
, which blocks until the task is finished.
You should use a CompletionService
which is used for exactly this purpose.
- Create
Executor
- Create
ExecutorCompletionService
using the Executor - Submit tasks via the
CompletionService
- Use
take
orpoll
on the CompletionService to wait for the tasks to finish - Repeat until all the tasks you submitted have finished
- Done
You can share an Executor with something else, just create the CompletionService
over the top and use it for your specific tasks.
Create CountDownLatch
with Y
as count and do latch.countDown()
in each of Y
tasks. In the end latch.await()
will ensure that all of the Y
tasks are completed.
精彩评论