java - 如何让线程等待任务完成?

标签 java multithreading

我试图用java编写一些线性代数库,并想使用CPU来实现多线程。为此,我创建了一个具有 8 个 ComputationThreadComputationMaster 类。

这个想法是,当任务被分配给 Master 时,它会将这个任务分配给所有线程,并且它们将处理该任务。

我的尝试如下:

任务是一个被调用直到返回false的方法。 该方法本身需要管理它正在工作的数据,但这不是问题本身的一部分。

public interface ComputationMethod {
    public boolean execute();
}

现在,我们来谈谈ComputationThread: 它扩展了Thread,看起来像这样:

ComputationMethod computation;

public ComputationThread(){
    super();
    this.start();
}

public void run(){
    while(!this.isInterrupted()){
        try{
            if(computation != null){
                while(computation.execute()){}
                computation = null;
                ComputationMaster.notify_thread_finished();
            }
        }catch (Exception e){
            e.printStackTrace();
            this.interrupt();
        }
    }
    this.interrupt();
}

您可以看到它通知 ComputationMaster 他已完成任务,因为任务本身返回了 false

最后,我将向您展示我对 ComputationMaster 的尝试:

public static final int MAX_THREAD_AMOUNT = 8;
public static Thread MAIN_THREAD;
private static ComputationThread[] threads = new ComputationThread[MAX_THREAD_AMOUNT];


static int finished = 0;
static synchronized void notify_thread_finished(){
    finished ++;
    if(finished == MAX_THREAD_AMOUNT){
        MAIN_THREAD.notifyAll();
        finished = 0;
    }
}
public static void compute(ComputationMethod method){
    for(ComputationThread t:threads){
        t.computation = method;
    }

    MAIN_THREAD = Thread.currentThread();
    try {
        MAIN_THREAD.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

这个想法是,当ComputationMaster获取一个计算方法时,它将把它交给所有线程并等待它们完成。 我还没有处理等待线程,所以我尝试保存当前线程并让它继续,一旦完成的线程的计数器等于线程总数。

这对我来说似乎很合乎逻辑,但我的代码存在多个问题:

  1. 抛出IllegalMonitorStateException
  2. 假设任务已完成,ComputationThreads 将进入无限循环并等待,直到给出新任务。 (也许让他们等待也可以做到)

我不想每次给出新任务时都创建一个新线程,并在任务完成后销毁它们。

最佳答案

我认为您不需要线程之间的所有信号传递。你可以只使用 thread.join

此外,一个小设计缺陷是线程处于无限旋转循环中,直到设置computation 成员为止。这会稍微降低你的初始性能。您应该在启动线程之前设置computation 成员。也就是说,不要让 ComputationThread 的构造函数调用 thread.start。在您的compute 函数中执行此操作。

这可能就是您所寻求的:

public static void compute(ComputationMethod method){
    for(ComputationThread t:threads){
        t.computation = method;
        t.start();
    }

    // wait for all threads to finish
    for(ComputationThread t:threads){
        t.join();
    }
}

然后你的运行函数被简化为:

public void run(){

   try {
       while(computation.execute()){}
   }
   catch (Exception e){
        e.printStackTrace();
   }
}

关于java - 如何让线程等待任务完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55781532/

相关文章:

java - Spring @Controller 未按预期返回 View

java - 在 JFrame 中配置 javaFX webengine

mysql - 如何使SQL查询线程启动,然后在获得结果之前做其他工作?

c# - WCF 是否会将来自同一客户端(使用不同线程)的并行调用转换为串行调用?

java - 为什么 Javadoc 会生成不兼容的 XHTML?

java - 无法使用 android 支持库 - NoClassDefFoundError : android. support.v7.appcompat.R$attr

java - Spring AMQP : [RabbitTemplate] Hystrix fallback is not getting invoked when RabbitTemplate ReturnCallback is executed

python - 在单独的线程中启动 flask 应用程序

java - 为什么不在构造函数中启动线程?如何终止?

c++ - 无锁pop()中使用引用参数返回值的缺点