并发解谜:Java并发-Cyclicbarrier。正确用法?

并发解谜:Java并发-Cyclicbarrier。正确用法?,java,multithreading,concurrency,barrier,Java,Multithreading,Concurrency,Barrier,我正试图写一个程序来解决两个谜题,它们不能独立解决,但有相同的解决方案。我的想法是,它们都在一个单独的线程中运行,直到它们停止寻找新的信息。然后,它们通过更新一些共享状态变量来交流所发现的内容,如果其中任何一个变量将某些内容写入共享状态,则继续 我认为骑自行车的人在这里是合适的。这是我的代码(在两个线程中并发运行: while (true) { doSolvingLogicHere(); shareUpdates(); // this method updat

我正试图写一个程序来解决两个谜题,它们不能独立解决,但有相同的解决方案。我的想法是,它们都在一个单独的线程中运行,直到它们停止寻找新的信息。然后,它们通过更新一些共享状态变量来交流所发现的内容,如果其中任何一个变量将某些内容写入共享状态,则继续

我认为骑自行车的人在这里是合适的。这是我的代码(在两个线程中并发运行:

while (true) {

        doSolvingLogicHere();

        shareUpdates(); // this method updates the shared state variable and is synhronized

        int count;
        int updates = 0;
        try {
            count = writeBarrier.await();
            updates = threadsUpdatedSomething;
            if (count == 0) {
                writeBarrier.reset();
                threadsUpdatedSomething = 0; //'reset' the shared value
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BrokenBarrierException ex) {
            Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (updates == 0) { //no thread updated something
            break;
        } else { // at least one of the threads updated something, solving should continue in both threads
            readUpdates();
        }
}
ThreadsUpdatedSomething是一个共享整数,在“ShareUpdates()中递增)'如果线程更新了任何内容。当两个线程在迭代中都没有发现任何新内容时,这意味着它们永远不会发现任何新内容,并且两个线程的整个循环都应该停止。这就是为什么我检查它是否为零

当两个线程都没有在共享状态变量中写入任何新信息时,我希望它们都停止。但是,当运行程序时,其中一个线程停止,而另一个线程继续运行。当调试程序并在“readUpdates()”行设置断点时,程序按预期工作

这是处理这种并发“求解”循环的正确方法吗?如果是正确的,代码中的错误在哪里

谢谢你的帮助

编辑:已更正小错误。“updates=threadsUpdatedSomething;”现在位于正确的位置,根据,
wait
返回

the arrival index of the current thread, where index getParties() - 1 indicates the first to arrive and zero indicates the last to arrive

 count = writeBarrier.await();
也就是说,只有一个线程会收到0。只有一个线程会将
updates
值设置为0。这就是为什么最后到达的线程会停止,而另一个线程不会停止

根据您的陈述,当发现两个线程都没有更新threadsUpdatedSomething时,您需要停止线程。我假设threadsUpdatedSomething的时间为零。 如果不是的话,你必须改变逻辑,一些人如何找到条件何时必须被打破并应用它

while (true) {

        doSolvingLogicHere();

        shareUpdates(); // this method updates the shared state variable and is synhronized

        int count;
        int updates = 0;
        try {
             writeBarrier.await();
            if (threadsUpdatedSomething == 0) {
                updates = threadsUpdatedSomething;
                writeBarrier.reset();
                threadsUpdatedSomething -= 2; //'reset' the counter by decrementing 2
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BrokenBarrierException ex) {
            Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (updates == 0) { //no thread updated something
            break;
        } else { // at least one of the threads updated something, solving should continue in both threads
            readUpdates();
        }
}

另外,如果需要,也不要忘记在异常情况下设置中断条件。

谢谢您的输入!我在“updates”赋值和“-=2”操作的位置上犯了一个小错误。我要做的是,只有最后一个线程重置了屏障,因此使用wait()的返回值应该是正确的。与其检查updates==0,我可以只检查threadsUpdatedSomething变量,但由于可能的竞争条件,此值可能已过期,因此这就是我使用“updates”变量的原因。我觉得这太复杂了,但我看不到协调线程的正确算法。我不知道看不到竞争场景。因为共享变量更新发生在wait()语句之前。在wait语句之后,除了要退出的场景(如果阻塞)之外,没有其他更新。