java CyclicBarrier未因重置而中断
我试图通过在开始(等待)几方(线程)中间重置循环障碍来测试BROKEN BARILVER异常,请找到下面的相同的示例代码。 用户类: CyclicBarrierTest类别: 因此,在运行上面的main()之后,我可以得到任何异常,并且“屏障破坏”也不会打印出来。线程只是在等待。 我在下面的链接中引用了CyclicBarrier API: 公共无效重置(): 将屏障重置为其初始状态。如果有的话 各方目前正在隔离墙等待,他们将带着 BrokenBarrier例外 但是我上面的代码似乎不能按照API描述工作,那么我上面的代码有什么问题,为什么不抛出BrokenBarrierException呢java CyclicBarrier未因重置而中断,java,multithreading,Java,Multithreading,我试图通过在开始(等待)几方(线程)中间重置循环障碍来测试BROKEN BARILVER异常,请找到下面的相同的示例代码。 用户类: CyclicBarrierTest类别: 因此,在运行上面的main()之后,我可以得到任何异常,并且“屏障破坏”也不会打印出来。线程只是在等待。 我在下面的链接中引用了CyclicBarrier API: 公共无效重置(): 将屏障重置为其初始状态。如果有的话 各方目前正在隔离墙等待,他们将带着 BrokenBarrier例外 但是我上面的代码似乎不能按照AP
您能帮忙吗?如果您想抛出异常,您必须确保
barrier.reset()代码>在cb.await()之后执行代码>,但这里是System.out.println(name+“user start!!!!”)
是一个非常昂贵的语句,它使barrier.reset()成为障碍代码>执行太早,您可以在barrier.reset()之前添加一个sleep语句代码>,说线程。睡眠(100)代码>
的文档已损坏
:
如果一方或多方因施工或上次重置后的中断或超时而冲出该屏障,或由于异常导致屏障操作失败,则为true;否则就错了
如果你想把它弄坏,你可以对聚会做点什么。您需要删除reset
以使线程等待
public class User implements Runnable {
private final String name;
private final CyclicBarrier cb;
public User(String name, CyclicBarrier cb) {
this.name = name;
this.cb = cb;
}
@Override
public void run() {
System.out.println(name+" user started !!!! ");
try {
cb.await(1,TimeUnit.SECONDS);
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name+" user ended !!!! ");
}
}
public class CyclicBarrierTest {
public static void main(String[] args) throws Exception {
CyclicBarrier barrier = new CyclicBarrier(5);
User user1 = new User("USER1", barrier);
new Thread(user1).start();
User user2 = new User("USER2", barrier);
new Thread(user2).start();
//Expected users are 5, but only 2 user threads started so far
// and resetting below which should throw barrier broken exception
Thread.sleep(100);
// barrier.reset();
Thread.sleep(1100);
if(barrier.isBroken()) {
System.out.println("Barrier broken ");
}
}
}
简短答复:
重置屏障时,屏障会丢失先前的BrokenBarrierException
(s)信息。因此,在reset
之后对isbreak
的任何调用都将返回false
javadoc对此进行了详细说明,尽管不是很清楚:
isbreak
返回:如果一方或多方由于自施工以来的中断或超时,或上次重置,或由于异常导致屏障操作失败,而脱离此屏障,则返回true;否则就错了
长答覆:
如果查看reset
和isbreak
的源代码,您可以更清楚地看到发生了什么:
public void reset() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
breakBarrier(); // break the current generation
nextGeneration(); // start a new generation
} finally {
lock.unlock();
}
}
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
}
private void nextGeneration() {
// signal completion of last generation
trip.signalAll();
// set up next generation
count = parties;
generation = new Generation();
}
private static class Generation {
boolean broken = false;
}
public boolean isBroken() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return generation.broken;
} finally {
lock.unlock();
}
}
您可以看到,参考generation.breaked
保存了有关破损屏障的信息。但在重置时,这将重新初始化为false
。感谢您的回答,现在我可以注意到异常,但仍然没有执行System.out.println(“屏障断开”)行。
public class User implements Runnable {
private final String name;
private final CyclicBarrier cb;
public User(String name, CyclicBarrier cb) {
this.name = name;
this.cb = cb;
}
@Override
public void run() {
System.out.println(name+" user started !!!! ");
try {
cb.await(1,TimeUnit.SECONDS);
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name+" user ended !!!! ");
}
}
public class CyclicBarrierTest {
public static void main(String[] args) throws Exception {
CyclicBarrier barrier = new CyclicBarrier(5);
User user1 = new User("USER1", barrier);
new Thread(user1).start();
User user2 = new User("USER2", barrier);
new Thread(user2).start();
//Expected users are 5, but only 2 user threads started so far
// and resetting below which should throw barrier broken exception
Thread.sleep(100);
// barrier.reset();
Thread.sleep(1100);
if(barrier.isBroken()) {
System.out.println("Barrier broken ");
}
}
}
public void reset() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
breakBarrier(); // break the current generation
nextGeneration(); // start a new generation
} finally {
lock.unlock();
}
}
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
}
private void nextGeneration() {
// signal completion of last generation
trip.signalAll();
// set up next generation
count = parties;
generation = new Generation();
}
private static class Generation {
boolean broken = false;
}
public boolean isBroken() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return generation.broken;
} finally {
lock.unlock();
}
}