Java - 基于时间步长同步多个线程

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()?

Kon*_*che 5

这正是障碍所在,您可以通过CyclicBarrierCountDownLatch实现这一点.这些是用于延迟线程进度直到达到所需状态的同步器,在这种情况下线程已完成计算.

这取决于您想要实现的细节:

锁存器用于等待事件; 障碍是等待其他线程.

对于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)

在所有线程完成计算之前,您的从属线程将不会继续.这样您就不需要在另一个主线程之间实现信令.

但是,如果您想要在所有线程到达该位置(主信令)后执行某些代码,则可以RunnableCyclicBarrier构造函数传递一个额外的代码,该构造函数将在所有线程到达屏障后执行.

this.barrier = new CyclicBarrier(count,
   new Runnable() {
      @Override
      public void run() {
         // signal your master thread, update values, etc.
      }
    }
 );
Run Code Online (Sandbox Code Playgroud)