4

对于集合点问题,我们需要同步两个线程,这是一个经典的解决方案:

aArrived = S(0);
bArrived = S(0);

线程 A:

while(true) {
  doSomething();
  aArrived.signal();
  bArrived.wait();
}

线程 B:

while(true) {
  doSomething();
  bArrived.signal();
  aArrived.wait();
}

这适用于两个线程,但是 N 个线程呢?对于 N=3,我们可以这样实现:

线程 A(其他线程是对称的):

while(true) {
  doSomething();
  aArrived.signal();
  aArrived.signal();
  bArrived.wait();
  cArrived.wait();
}

我发现的所有来源都只是声明:“再次考虑第 3.2 节中的 Rendezvous 问题。我们提出的解决方案的一个限制是它不适用于两个以上的线程。” ,或“之前提出的解决方案不适用于两个以上的线程。” .

(顺便说一句,这里提出的通用解决方案可能不是最优的,因为它会为 N 个线程使用 N 个信号量......我只是好奇是否有人有这种解决方案不适用于 N>2 个线程的场景?)

4

1 回答 1

0

如果您CyclicBarrier在 Java 中使用 a 会非常简单,因为它会为您做这种事情。但是对于一般情况,您将如何执行此操作并自己编写?你可以做一些类似于 aCountdownLatchCyclicBarrier所做的事情。

保持对预期参与方数量的计数,当他们接近你的障碍时减少它,然后在减少的计数为 0 时通知所有人。例如:(这非常简单)。

class CountdownBarrier {
   private int numberOfParties;
   private final Object lock = new Object();
   public CountdownBarrier(int numberOfParties){ this.numberOfParties = ..}

   public void arriveAndAwait(){  
      synchronized(lock){  
         if(--numberOfParties == 0)
            lock.notifyAll();  
         while(numberOfParties != 0)
            lock.wait();       
      }
   }
} 

然后

CountdownBarrier barrier = new CountdownBarrier(3);

Thread A:
   barrier.arriveAndAwait();
Thread B: 
   barrier.arriveAndAwait();
Thread C:
   barrier.arriveAndAwait(); // assuming time progresses downward, this arriveAndAwait will notify all threads to wake up and continue.

同样可以在 Java 中使用

CyclicBarrier#await();

或者

CountdownLatch#countDown(); // then
CountdownLatch#await();
于 2015-01-20T22:57:14.713 回答