4

ランデブーの問題については、2 つのスレッドを同期する必要があります。これが古典的な解決策です。

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

スレッド A:

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

スレッド B:

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

これは 2 スレッドの場合はうまくいきますが、N スレッドの場合はどうでしょうか。N=3 の場合、次のように実装できます。

スレッド A (他のスレッドは対称):

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

私が見つけたすべての情報源は、次のように述べています。、または「以前に提示された解決策は、3 つ以上のスレッドでは機能しません。」.

(ちなみに、ここで提示された一般化されたソリューションは、N 個のスレッドに対して N 個のセマフォを使用するため、おそらく最適ではありません...このソリューションが N>2 スレッドで機能しないというシナリオを誰かが持っているかどうか知りたいです?)

4

1 に答える 1

0

CyclicBarrierこの種のことを行うため、Javaでa を使用すると非常に簡単になります。しかし、一般的なケースでは、どのようにこれを行い、自分で記述しますか? CountdownLatchorと同様のことができますCyclicBarrier

予想されるパーティー数のカウントを維持し、彼らがバリアに近づくにつれて減少させ、減少したカウントが 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 に答える