Java 自行车运载器未按预期工作
我正在尝试使用Java 自行车运载器未按预期工作,java,concurrency,cyclicbarrier,Java,Concurrency,Cyclicbarrier,我正在尝试使用CyclicBarrier模拟一场triatlon比赛,但它没有达到预期效果,我不知道为什么 比赛的每一部分都要等到所有的参赛者都完成了前一部分,但这似乎是永远的等待 这是第一阶段的代码: class Runner implements Runnable { private CyclicBarrier bar = null; private static int runners; private static double[] time; priva
CyclicBarrier
模拟一场triatlon比赛,但它没有达到预期效果,我不知道为什么
比赛的每一部分都要等到所有的参赛者都完成了前一部分,但这似乎是永远的等待
这是第一阶段的代码:
class Runner implements Runnable
{
private CyclicBarrier bar = null;
private static int runners;
private static double[] time;
private int number;
public static String name;
public Runner(int runners, String name)
{
time = new double[runners];
for (int i=0; i<runners; i++)
time[i] = 0;
this.name= name;
}
public Runner(CyclicBarrier bar, int number)
{
this.bar = bar;
this.number = number;
}
public void run()
{
try { int i = bar.await(); }
catch(InterruptedException e) {}
catch (BrokenBarrierException e) {}
double tIni = System.nanoTime();
try { Thread.sleep((int)(100*Math.random()); } catch(InterruptedException e) {}
double t = System.nanoTime() - tIni;
time[number] += t;
}
}
public class Triatlon
{
public static void main(String[] args)
{
int runners = 100;
CyclicBarrier Finish_Line_1 = new CyclicBarrier (runners);
Runner c = new Runner(runners, "Triatlon");
ExecutorService e = Executors.newFixedThreadPool(runners);
for (int i=0; i<runners; i++)
e.submit(new Runner(Finish_Line_1, i));
System.out.println(Finish_Line_1.getNumberWaiting()); // this always shows 99
try { int i = Finish_Line_1.await(); }
catch(InterruptedException e01) {}
catch (BrokenBarrierException e02) {}
System.out.println("Swimming phase completed");
// here the rest of the competition, which works the same way
}
}
类运行程序实现可运行
{
专用循环载波条=null;
私家车;
私有静态双[]时间;
私有整数;
公共静态字符串名;
公共运行程序(int运行程序,字符串名称)
{
时间=新的双人[跑步者];
对于(int i=0;i您有一个off by one错误:您为100个线程创建了一个CyclicBarrier
,但执行101个await
s,这个一次性方法在main方法中。由于循环屏障的语义,并且受不确定条件的影响,您的主线程将是最后一个执行await
的线程,因此留下一个错误。)孤独地等待另外99个线程加入
解决此问题后,您会发现应用程序即使在所有工作完成后仍保持运行。这是因为您没有调用e.shutdown()
,所以池中的所有线程在主线程完成后都保持活动状态
顺便说一句,getNumberWaiting
始终为我显示0,这是由于100个提交的线程到达屏障而降低屏障后的预期值。但是,这是不确定的,并且可以随时更改。CyclicBarrier
在各方调用Wait并打开屏障后循环。因此名称
因此,如果您用5个参与方创建它,并且有6个调用await
,最后一个将触发它再次等待4个参与方加入
这基本上就是这里发生的事情,因为你在你的main中有一个额外的wait
调用。它正在等待另一个runner-1调用发生
简单的解决方法是创建
CyclicBarrier
和runners+1个团队。你已经明白了重点。我想补充一点,我认为应该是Thread.sleep(…)
thenbarrier.await()
在每个运行方法中。实际上,运行者运行,然后等待其他人运行join@Grooveek这将更有意义,是的,并且会掩盖OP的错误,因为池中的一个线程将被卡住。根据代码的其余部分,错误可能会在下一段中冒出来,其来源更加模糊。谢谢!这为m提供了一个解决方案y问题。但我看到了一个异常。打印“游泳阶段完成”后,程序没有完成,好像它在等待其他任何事情发生。您在这里的评论也使程序工作,但我不明白两件事:1)为什么它更有意义,因为在运行跑步者之前放置障碍(Thread.sleep)(…)
)意味着所有跑步者都准备好出发了,所以当障碍解除时,他们都一起开始比赛;2)为什么这样做会掩盖错误?我想第2和第3阶段跑步者98和99出现的问题正是因为“卡线”你说的是…老实说,我不知道如何解决这个问题。