Tru*_*rup 5 java multithreading
假设我有一个Master,它保存SlaveThread对象列表.在每个时间步,我希望Master并行运行SlaveThreads,但是,在时间步的结束时,我希望SlaveThreads在向前推进之前等待彼此完成当前时间步.另外,我不想在每个时间步重新实现SlaveThreads.我有两个可能的解决方案,我不知道如何让它们中的任何一个工作:
1)SlaveThread中的run()方法处于while(true)循环中.在SlaveThread中执行单个循环后,我会让SlaveThread通知Master(我不知道该怎么做),而Master会做类似的事情
try{
for (int i = 0; i < numSlaveThreads; i++) {
while (!slaveThreads[i].getCompletedThisIter()) {
wait()
}
}
System.out.println("Joined");
Run Code Online (Sandbox Code Playgroud)
}
在进入下一个时间步之前.我该怎么做?如何让单个SlaveThread只通知主服务器?
2)Slave中的run()不在while(true)循环中,然后我必须在每次迭代时调用start().但是此时Slave的线程状态将被终止.如何在不重新实例化的情况下再次调用start()?
这正是障碍所在,您可以通过CyclicBarrier或CountDownLatch实现这一点.这些是用于延迟线程进度直到达到所需状态的同步器,在这种情况下线程已完成计算.
这取决于您想要实现的细节:
锁存器用于等待事件; 障碍是等待其他线程.
对于CyclicBarrier那将以下列方式完成:
// whereby count is the number of your slave threads
this.barrier = new CyclicBarrier(count);
Run Code Online (Sandbox Code Playgroud)
然后在Runnable您的从属定义中,您将在计算结束时插入:barrier.await()
public class Slaves implements Runnable {
// ...
@Override
public void run() {
while(condition) {
// computation
// ...
try {
// do not proceed, until all [count] threads
// have reached this position
barrier.await();
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在所有线程完成计算之前,您的从属线程将不会继续.这样您就不需要在另一个主线程之间实现信令.
但是,如果您想要在所有线程到达该位置(主信令)后执行某些代码,则可以Runnable向CyclicBarrier构造函数传递一个额外的代码,该构造函数将在所有线程到达屏障后执行.
this.barrier = new CyclicBarrier(count,
new Runnable() {
@Override
public void run() {
// signal your master thread, update values, etc.
}
}
);
Run Code Online (Sandbox Code Playgroud)