Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java CyclicBarrier未因重置而中断_Java_Multithreading - Fatal编程技术网

java CyclicBarrier未因重置而中断

java CyclicBarrier未因重置而中断,java,multithreading,Java,Multithreading,我试图通过在开始(等待)几方(线程)中间重置循环障碍来测试BROKEN BARILVER异常,请找到下面的相同的示例代码。 用户类: CyclicBarrierTest类别: 因此,在运行上面的main()之后,我可以得到任何异常,并且“屏障破坏”也不会打印出来。线程只是在等待。 我在下面的链接中引用了CyclicBarrier API: 公共无效重置(): 将屏障重置为其初始状态。如果有的话 各方目前正在隔离墙等待,他们将带着 BrokenBarrier例外 但是我上面的代码似乎不能按照AP

我试图通过在开始(等待)几方(线程)中间重置循环障碍来测试BROKEN BARILVER异常,请找到下面的相同的示例代码。 用户类:

CyclicBarrierTest类别:

因此,在运行上面的main()之后,我可以得到任何异常,并且“屏障破坏”也不会打印出来。线程只是在等待。

我在下面的链接中引用了CyclicBarrier API:

公共无效重置():

将屏障重置为其初始状态。如果有的话 各方目前正在隔离墙等待,他们将带着 BrokenBarrier例外

但是我上面的代码似乎不能按照API描述工作,那么我上面的代码有什么问题,为什么不抛出BrokenBarrierException呢


您能帮忙吗?

如果您想抛出异常,您必须确保
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();
    }
}