Java-优雅地退出线程

Java-优雅地退出线程,java,concurrency,cyclicbarrier,Java,Concurrency,Cyclicbarrier,我有一堆执行计算的线程。它们是使用一个“同步”的。当任何线程的run()方法完成时,我希望所有其他线程在下次调用屏障上的wait()时也退出 到目前为止,我尝试的所有方法要么挂起await()调用,要么导致屏障被打破。有什么建议吗 编辑:以下是(基本)代码: reset()将用抛出的异常唤醒所有等待的线程 然后,您可以使用wait as so private static volatile boolean shouldStop=false; public void run() { tr

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

到目前为止,我尝试的所有方法要么挂起
await()
调用,要么导致屏障被打破。有什么建议吗

编辑:以下是(基本)代码:

reset()将用抛出的异常唤醒所有等待的线程

然后,您可以使用wait as so

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)
检查的方法,从它的声音中您可能想要一个。假设您知道线程/参与者的数量,只需为这么多线程创建一个,然后在线程完成后倒计时并等待闩锁:

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

void doSomething() throws InterruptedException {
  …
  latch.countDown();
  latch.await(); // blocks, throws InterruptedException
}
CyclicBarrier
相比,
CountDownLatch
不可重用,只能使用一次。然而,它将等待和释放问题分开,因此您可以使用另一个线程来允许线程通过

综上所述,如果您确实需要
CyclicBarrier
对上述代码稍加修改即可:


但是,如果任何线程被中断或调用了
barrier.reset()
,那么barrier就会被破坏并引发异常。

显示代码,这很难回答。@ryst,我认为CyclicBarrier不会做你想做的。@Peter Lawrey:那么我还应该选择什么呢。它实际上非常适合我的问题(除了退出部分)。您是否进行了充分的同步,以便其他线程可以看到对影响
someCondition
的变量所做的更改?显示更多代码,特别是什么是“someCondition”并显示其中所有内容的对象声明。如果障碍因其他原因而打破,该怎么办?你的解决方案实际上就像我现在已经实现了一样,但我不满意。@ryyst,你不满意什么?在不知道这一点的情况下,很难提出替代方案。在捕获中进行额外检查,但如果屏障被破坏,则需要进行一些额外的同步,然后才能继续,并且只有在使用超时和中断(或屏障操作引发异常)时才会发生破坏
final int workers = …
final CountDownLatch latch = new CountDownLatch(workers);

void doSomething() throws InterruptedException {
  …
  latch.countDown();
  latch.await(); // blocks, throws InterruptedException
}
final int workers = …
final CyclicBarrier barrier = new CyclicBarrier(workers);

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