在线程上监督Runnables的调用

时间:2012-04-19 18:48:07

标签: java multithreading concurrency runnable executorservice

好吧,我会通过举例来解释我的问题。

假设我试图在给定时实现并行合并算法:

db 是一个数组,其中 db [i] 是对象的ArrayList。

j 是它的大小。 合并(db,cmp,i,j)是一个可将 db [j] 合并到 db [i]中的runnable。< / em>的

cmp是相关的比较器。

这是我首先完成的事情:

    ExecutorService e =  Executors.newFixedThreadPool(3);
    while (j>0) 
        for ( i=0;i<j;i++,j--) 
            e.execute(new Merger<E>(db,cmp,i,j));

但随后开始了一些合并,而之前需要先完成的合并尚未完成。 (更不用说正在运行的线程在合并完成之前完成了循环方式......)并且这使我的程序踢出了一个Exeception。

这是我不能做的,但是想要做,因此需要你的帮助:

    ExecutorService e =  Executors.newFixedThreadPool(3);
    while (j>0) {
        for ( i=0;i<j;i++,j--) 
            e.execute(new Merger<E>(db,cmp,i,j));
        wait for e to announce that all runnables have finished running;
    }

在我看来这应该有用,如果你认为没有解释原因,但无论如何,我想知道它是如何完成的。

(基本上我可以实现我自己的FixedThreadPool版本,以使其成为但是我不愿意)

3 个答案:

答案 0 :(得分:2)

您可能正在寻找CountDownLatch

  • 确定您需要等待的线程数,并创建一个具有该数字的CountDownLatch
  • 在构建锁定时将锁存器传递给所有工作线程,并在完成后让它们调用countDown()
  • 在将工作线程排入队列的循环之后,await()倒计时到达零。

答案 1 :(得分:1)

你需要一个'startAndRendezvous'runnable来发布合并并等待它们完成。通常,这是通过创建一组合并可运行任务来完成的,这些任务使用指向startAndRendezvous中的CountDownlatch的回调设置,或者更灵活地将startAndRendezvous作为构造函数参数传递给合并runnables。

最新的Java有一个ForkJoinPool。看一下这个类 - 它可以节省一个明确的倒计时锁存器。

答案 2 :(得分:-1)

一种简单的方法应该是在Merger中定义一个静态计数器:

public class Merger<E> ... {
  public static int runningCount=0;
  public Merger(...){
    runningCount++;
  }
  public void run(){
     ...
     runnningCount--;
  }
}

然后:

ExecutorService e =  Executors.newFixedThreadPool(3);    
while (j>0) {
    for ( i=0;i<j;i++,j--) 
        e.execute(new Merger<E>(db,cmp,i,j));
    while(Merger.runningCount>0)
        Thread.sleep(10);
}