我有一堆执行计算的线程。它们使用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();
}
}
答案 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()
被调用,则屏障被破坏并抛出异常。