开发者

Waiting for a subset of threads in a Java ThreadPool

开发者 https://www.devze.com 2023-02-03 00:19 出处:网络
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).

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 Runnables, just invokeAll() some Callables - 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 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消