我正在尝试编写一个程序来解决两个无法独立解决但具有相同解决方案的难题。我的想法是它们都在一个单独的线程中运行,直到它们停止寻找新的信息。然后他们通过更新一些共享状态变量来传达他们发现的内容,并在其中任何一个写入共享状态时继续。
我认为 CyclicBarrier 是在这里使用的适当机制。这是我的代码(在 2 个线程中同时运行:
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()”行设置断点时,程序按预期工作。
这是处理这种并发“解决”循环的正确方法吗?如果它是正确的,我的代码中的错误在哪里?
谢谢您的帮助!
编辑:纠正了小错误。'更新 = 线程更新的东西;' 现在在正确的地方