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。假设您知道线程/参与者的数量,您只需为那么多创建一个,然后当您的线程完成倒计时并等待闩锁:

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

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

相比CyclicBarrier,CountDownLatch是不可重复使用的,你只能使用一次。但是,它确实将等待和释放问题分开,因此您可以例如拥有另一个允许线程通过的线程。

综上所述,如果您确实需要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 回答