Java 线程上可运行程序的监督调用

Java 线程上可运行程序的监督调用,java,multithreading,concurrency,runnable,executorservice,Java,Multithreading,Concurrency,Runnable,Executorservice,好的,我会举例说明我的问题 假设在给定以下条件时,我正在尝试实现并行合并算法: db是一个数组,其中db[i]是对象的ArrayList j是它的大小。 合并(db,cmp,i,j)是将db[j]合并到db[i]的可运行程序 cmp是一个相关的比较器 这是我首先做的: ExecutorService e = Executors.newFixedThreadPool(3); while (j>0) for ( i=0;i<j;i++,j--)

好的,我会举例说明我的问题

假设在给定以下条件时,我正在尝试实现并行合并算法:

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

j是它的大小。 合并(db,cmp,i,j)是将db[j]合并到db[i]的可运行程序

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));
ExecutorService e=Executors.newFixedThreadPool(3);
而(j>0)
对于(i=0;i0){

对于(i=0;i您需要一个“startAndRendezvous”可运行任务集来发出合并并等待它们完成。通常,这是通过创建一组合并可运行任务集来完成的,其中回调指向startAndRendezvous中的CountDownlatch,或者更灵活地,将startAndRendezvous作为构造函数参数传递给合并可运行任务集


最新的Java有一个ForkJoinPool。看看这个类,它省去了一个显式的倒计时闩锁。

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

public class Merger<E> ... {
  public static int runningCount=0;
  public Merger(...){
    runningCount++;
  }
  public void run(){
     ...
     runnningCount--;
  }
}
公共类合并{
公共静态int runningCount=0;
公开合并(……){
runningCount++;
}
公开募捐{
...
运行计数--;
}
}
然后:

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);
}
ExecutorService e=Executors.newFixedThreadPool(3);
而(j>0){
对于(i=0;i0)
睡眠(10);
}

您可能正在寻找:

  • 确定需要等待的线程数,并使用该数创建一个
    CountDownLatch
  • 构造工作线程时,将闩锁传递给所有工作线程,并让它们在完成后调用
    countDown()
  • 使工作线程排队的循环结束后,
    等待()
    倒计时达到零

比如如何?你的答案太抽象了RunningCount必须是一个原子整数,否则就不起作用。而且自旋锁定很少是最好的主意——即使循环有一个线程。sleep。@yshavit=yes,或已锁定。sleep()循环很糟糕-例如,有Wait/Notify。另外,现在有了ForkJoinPool类。感谢您的反馈,我没有这样做。由@Philipp-Reichart提供的解决方案看起来更好
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);
}