我试图用java编写一些线性代数库,并想使用CPU来实现多线程。为此,我创建了一个具有 8 个 ComputationThread
的 ComputationMaster
类。
这个想法是,当任务被分配给 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
获取一个计算方法时,它将把它交给所有线程并等待它们完成。
我还没有处理等待线程,所以我尝试保存当前线程并让它继续,一旦完成的线程的计数器等于线程总数。
这对我来说似乎很合乎逻辑,但我的代码存在多个问题:
- 抛出
IllegalMonitorStateException
。 - 假设任务已完成,
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/