好吧,我会通过举例来解释我的问题。
假设我试图在给定时实现并行合并算法:
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版本,以使其成为但是我不愿意)
答案 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);
}