等待Java ThreadPool中的线程子集

时间:2011-01-08 17:51:39

标签: java concurrency threadpool

假设我有一个包含X项的线程池,并且给定的任务使用了Y这些项目(其中Y远小于X)。< / p>

我想等待给定任务的所有线程(Y项)完成,而不是整个线程池。

如果线程池的execute()方法返回了对所用线程的引用,我可以join()对这些Y个线程中的每一个进行简化,但事实并非如此。

有谁知道一种优雅的方法来实现这一目标?感谢。

4 个答案:

答案 0 :(得分:3)

而不是execute() Runnable s,而只是invokeAll()一些Callable s - 然后您可以为每个Future获得get() {{1}} {{1}} 1}},阻止任务完成。

答案 1 :(得分:3)

您可以使用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)任务。

答案 2 :(得分:2)

您应该使用CompletionService来实现此目的。

  • 创建Executor
  • 使用执行者
  • 创建ExecutorCompletionService
  • 通过CompletionService
  • 提交任务
  • 在CompletionService上使用takepoll等待任务完成
  • 重复直到您提交的所有任务都已完成
  • 完成

您可以与其他人共享Executor,只需在顶部创建CompletionService并将其用于特定任务。

答案 3 :(得分:0)

使用CountDownLatch作为计数创建Y,并在每个latch.countDown()任务中执行Y。最后latch.await()将确保完成所有Y任务。