首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CyclicBarrier未按预期工作

CyclicBarrier未按预期工作
EN

Stack Overflow用户
提问于 2013-12-20 18:02:36
回答 2查看 1.4K关注 0票数 2

我试着用CyclicBarrier来模拟铁人三项比赛,但是它并没有像预期的那样工作,我也不知道为什么。

比赛的每一部分都要等到所有的选手都完成了前一项比赛,但似乎是永远在等待。

这是第一阶段的代码:

代码语言:javascript
复制
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
}
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-20 18:46:43

CyclicBarrier循环,一旦所有各方都呼叫,等待和障碍被打开。于是就得名了。因此,如果您用5个参与者创建它,并且有6个对await的调用,最后一个调用将触发它再次等待另外4个参与者加入。

这基本上就是在这里发生的事情,因为您的主服务器中有一个额外的await调用。它正在等待另一名跑步者--1次呼叫发生。

简单的解决办法是创建带有CyclicBarrier各方的runners+1。

票数 2
EN

Stack Overflow用户

发布于 2013-12-20 18:32:18

您有一个断断续续的错误:您为100个线程创建了一个CyclicBarrier,但是执行101个awaits,这个一次性在主方法中。由于循环屏障的语义,并且在不确定的条件下,您的主线程将是执行await的最后一个线程,因此只能等待另外99个线程加入。

在修复了这个问题之后,您会发现即使在完成所有工作之后,应用程序也会继续运行。这是因为您没有调用e.shutdown(),所以在主线程完成后,池中的所有线程都保持活动状态。

顺便说一句,getNumberWaiting总是为我显示0,这是由于100个提交的线程到达屏障后的期望值。然而,这是不确定的,而且随时可能发生变化。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20709447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档