2

計算を実行するスレッドがたくさんあります。を使用して「同期」されCyclicBarrierます。いずれかのスレッドのrun()メソッドが終了したら、次回バリアを呼び出したら、他のすべてのスレッドも終了するようにします。await()

これまでのところ、私が試したことはすべて、await()呼び出しでハングするか、バリアが壊れてしまいます。任意のヒント?

編集: (基本的な) コードは次のとおりです。

public MyClass implements Runnable {
    public void run() {
        while (true) {
            if (someCondition) {
                // quit other threads when they call await()
                return;
            }
            barrier.await();
    }
}
4

2 に答える 2

3

reset() は、スローされた例外で待機中のすべてのスレッドを目覚めさせます

その後、awaitをそのまま使用できます

private static volatile boolean shouldStop=false;

public void run() {
    try{
        while (true) {
            if (someCondition) {
                // quit other threads when they call await()
                return;
            }
            try{
                if(shouldStop)return;
                barrier.await();
            }catch(BrokenBarrierException e){
                //someone stopped 
                return;
            }
       }
   }finally{
       shouldStop =true;
       barrier.reset();
   }
}

if(shouldStop)チェックのメソッドを呼び出すこともできます

于 2011-06-28T21:22:44.650 に答える
0

その音から、おそらくCountDownLatchが必要です。スレッド/参加者の数がわかっていると仮定すると、その数に対して 1 つを作成し、スレッドが終了したらカウントダウンしてラッチを待ちます。

final int workers = …
final CountDownLatch latch = new CountDownLatch(workers);

void doSomething() throws InterruptedException {
  …
  latch.countDown();
  latch.await(); // blocks, throws InterruptedException
}

に比べCyclicBarrierCountDownLatchは再利用できず、一度しか使用できません。ただし、待機と解放の懸念を分離するため、たとえば、スレッドの通過を許可する別のスレッドを作成できます。

CyclicBarrierとはいえ、上記のコードにわずかなバリエーションが必要な場合は、次のように動作するはずです。

final int workers = …
final CyclicBarrier barrier = new CyclicBarrier(workers);

void doSomething() throws InterruptedException, BrokenBarrierException {
  …
  latch.await(); // blocks, throws InterruptedException, BrokenBarrierException
}

ただし、いずれかのスレッドが中断されるかbarrier.reset()呼び出されると、バリアが壊れて例外がスローされます。

于 2011-06-28T23:45:33.680 に答える