简体   繁体   中英

Waiting for a subset of threads in a Java ThreadPool

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 want 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.

而不是execute() Callable Runnable ,而只是Callable invokeAll()一些Callable s-然后,您将获得一个Future ,可以在每个Future上调用get() ,该方法将阻塞直到任务完成。

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.

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 or poll 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM