gpt4 book ai didi

java - 为什么 CyclicBarrier reset() 方法抛出 BrokenBarrierException

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:23:16 25 4
gpt4 key购买 nike

我的目的很简单。我想使用 CyclicBarrier 和它的 reset() 方法使用下面提到的代码运行 3 个线程 4 次。在 net 、Concurrency in practiceThinking in Java 中研究了所有可能的资源。无法按照我想要的方式解决它。在Thinking in Java 中,HorseRace.Java 下有一种此类解决方案,但它使用了 Executor 服务。我只想使用 CyclicBarrierreset() 方法来做这件事。这是我的代码和输出,它运行到结束但在 reset() 方法后抛出 BrokenBarrierException

package com.apal.barrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierEx1 {
CyclicBarrier cb;
public static int count = 0;

public static void main(String[] args) {
new CyclicBarrierEx1().manageThread();
}

private void manageThread() {
cb = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
if (count == 3) {
System.out.println("Exit from system");
return;
}
System.out.println("Collating task");
cb.reset();
for (int i = 0; i < 3; i++) {
new Thread(new Worker(cb)).start();
}
count++;
}
});

for (int i = 0; i < 3; i++) {
new Thread(new Worker(cb)).start();
}
}
}

class Worker implements Runnable {
CyclicBarrier cb;

public Worker(CyclicBarrier cb) {
this.cb = cb;
}

@Override
public void run() {
doSomeWork();
try {
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}

private void doSomeWork() {
System.out.println("Doing some work ");
}
}

示例输出

Doing some work 
Doing some work
Doing some work
Collating task
Doing some work
Doing some work
Doing some work
Collating task
Doing some work
java.util.concurrent.BrokenBarrierExceptionDoing some work
Doing some work
Collating task
Doing some work

at java.util.concurrent.CyclicBarrier.dowait(Unknown Source)
at java.util.concurrent.CyclicBarrier.await(Unknown Source)
at com.apal.barrier.Worker.run(CyclicBarrierEx1.java:48)
at java.lang.Thread.run(Unknown Source)
java.util.concurrent.BrokenBarrierException
at java.util.concurrent.CyclicBarrier.dowait(Unknown Source)
at java.util.concurrent.CyclicBarrier.await(Unknown Source)
Doing some work at com.apal.barrier.Worker.run(CyclicBarrierEx1.java:48)

at java.lang.Thread.run(Unknown Source)
Doing some work
Exit from systemjava.util.concurrent.BrokenBarrierException

at java.util.concurrent.CyclicBarrier.dowait(Unknown Source)
at java.util.concurrent.CyclicBarrier.await(Unknown Source)
at com.apal.barrier.Worker.run(CyclicBarrierEx1.java:48)
at java.lang.Thread.run(Unknown Source)
java.util.concurrent.BrokenBarrierException
at java.util.concurrent.CyclicBarrier.dowait(Unknown Source)
at java.util.concurrent.CyclicBarrier.await(Unknown Source)
at com.apal.barrier.Worker.run(CyclicBarrierEx1.java:48)
at java.lang.Thread.run(Unknown Source)
java.util.concurrent.BrokenBarrierException
at java.util.concurrent.CyclicBarrier.dowait(Unknown Source)
at java.util.concurrent.CyclicBarrier.await(Unknown Source)
at com.apal.barrier.Worker.run(CyclicBarrierEx1.java:48)
at java.lang.Thread.run(Unknown Source)
java.util.concurrent.BrokenBarrierException
at java.util.concurrent.CyclicBarrier.dowait(Unknown Source)
at java.util.concurrent.CyclicBarrier.await(Unknown Source)
at com.apal.barrier.Worker.run(CyclicBarrierEx1.java:48)
at java.lang.Thread.run(Unknown Source)

最佳答案

当在 CyclicBarrier 构造函数中传递的屏障操作运行时,您会遇到竞争条件。 The docs for CyclicBarrier.await()说说该操作方法是如何运行的(强调已添加):

If the current thread is the last thread to arrive, and a non-null barrier action was supplied in the constructor, then the current thread runs the action before allowing the other threads to continue.

这意味着屏障操作方法对 reset() 的调用可以在其他线程仍在等待屏障时发生。这将导致 BrokenBarrierException

请参阅以“如果屏障操作不依赖于执行时挂起的各方,则该方中的任何线程都可以在释放时执行该操作”开头的段落的文档。使用该技术,您可以在一个工作线程刚从 await() 释放后执行您当前在操作例程中执行的工作。以下是未经测试的尝试(注意 - 我还重新调整了 count 变量递增的位置,以避免工作线程可能在 count 开始递增之前完成的竞争条件) :

package com.apal.barrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierEx1 {
CyclicBarrier cb;
public static int count = 0;

public static void main(String[] args) {
new CyclicBarrierEx1().manageThread();
}

public static void barrierComplete(CyclicBarrier cb) {
System.out.println("Collating task");

if (count == 3) {
System.out.println("Exit from system");
return;
}
count++;

for (int i = 0; i < 3; i++) {
new Thread(new Worker(cb)).start();
}
}

private void manageThread() {
cb = new CyclicBarrier(3);

for (int i = 0; i < 3; i++) {
new Thread(new Worker(cb)).start();
}
}
}


class Worker implements Runnable {
CyclicBarrier cb;

public Worker(CyclicBarrier cb) {
this.cb = cb;
}

@Override
public void run() {
doSomeWork();
try {
if (cb.await() == 0) {
CyclicBarrierEx1.barrierComplete(cb);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}

private void doSomeWork() {
System.out.println("Doing some work ");
}
}

关于java - 为什么 CyclicBarrier reset() 方法抛出 BrokenBarrierException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25862411/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com