简体   繁体   English

等待Java ThreadPool中的线程子集

[英]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 ). 比方说,我有一个包含一个线程池X项目,以及给定的任务采用Y这些项目(其中Y远小于X )。

I want to wait for all of the threads of a given task ( Y items) to finish, not the entire thread pool. 我要等待给定任务的所有线程( Y项目)完成,而不是整个线程池完成。

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. 如果线程池的execute()方法返回对所用线程的引用,则我可以简单地将join()与这些Y线程的每一个进行join() ,但事实并非如此。

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. 您可以使用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();
}

So each thread that is running type Y will wait until all those Y's have completed. 因此,每个运行类型Y的线程都将等待,直到所有这些Y完成。 Note you have to add 1 to the barrier size to account for the initially executing thread to wait also. 请注意,您必须在屏障大小上加1以说明最初执行的线程也要等待。

Also Note: If Michael Borgwardt's example works for you that would be best. 另请注意:如果Michael Borgwardt的示例对您有用,那将是最佳选择。 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. 但是,如果您需要线程池,则对于每个正在运行Y的线程,不要运行其他任何非Y的线程,那么我的解决方案将是您唯一的方法。 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. Future.get()将仅阻塞调用线程,并且当线程池完成Y的执行时,它将随后执行其他一些任务(可能是非Y任务)。

You should use a CompletionService which is used for exactly this purpose. 您应使用完全用于此目的的CompletionService

  • Create Executor 创建Executor
  • Create ExecutorCompletionService using the Executor 创建ExecutorCompletionService使用执行人
  • Submit tasks via the CompletionService 通过CompletionService提交任务
  • Use take or poll on the CompletionService to wait for the tasks to finish 使用takepoll对下,CompletionService等待任务完成
  • 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. 您可以与其他人共享执行器,只需在顶部创建CompletionService并将其用于特定任务即可。

Create CountDownLatch with Y as count and do latch.countDown() in each of Y tasks. 创建以Y为count的CountDownLatch ,并在每个Y任务中执行latch.countDown() In the end latch.await() will ensure that all of the Y tasks are completed. 最后, latch.await()将确保所有Y任务均已完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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