Java - 优雅地退出线程

时间:2011-06-28 21:01:40

标签: java concurrency cyclicbarrier

我有一堆执行计算的线程。它们使用CyclicBarrier“同步”。当任何线程的run()方法完成时,我希望所有其他线程在下次调用屏障await()时也要退出。< / p>

到目前为止,我尝试的所有内容都会在await()来电时挂起或导致屏障破裂。有什么提示吗?

编辑:这是(基本)代码:

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

2 个答案:

答案 0 :(得分: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)检查

的方法

答案 1 :(得分: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()被调用,则屏障被破坏并抛出异常。