如何让java.concurrency.CyclicBarrier按预期工作

时间:2010-03-26 09:38:02

标签: java concurrency multithreading cyclicbarrier

我正在编写将产生两个线程的代码,然后等待它们使用CyclicBarrier类进行同步。问题是循环障碍没有按预期工作,主线程不等待各个线程完成。以下是我的代码的外观:

 class mythread extends Thread{
   CyclicBarrier barrier;
   public mythread(CyclicBarrier barrier) { 
       this.barrier = barrier;
      }

   public void run(){
            barrier.await();
       } 
 }



class MainClass{
 public void spawnAndWait(){
    CyclicBarrier barrier = new CyclicBarrier(2);
    mythread thread1 = new mythread(barrier).start();
    mythread thread2 = new mythread(barrier).start();
    System.out.println("Should wait till both threads finish executing before printing this");
  }
}

知道我做错了什么吗?或者有更好的方法来编写这些屏障同步方法吗?请帮忙。

4 个答案:

答案 0 :(得分:14)

在执行主线程期间,您创建另外两个线程并告诉它们彼此等待。但你没有写任何东西让你的主线程等待他们并抱怨它不等待。尝试

CyclicBarrier barrier = new CyclicBarrier(3);
mythread thread1 = new mythread(barrier).start();
mythread thread2 = new mythread(barrier).start();
barrier.await(); // now you wait for two new threads to reach the barrier.
System.out.println("Should wait till both threads finish executing before printing this");

顺便说一句。除非必须,否则不要扩展Thread类。实现Runnable并将实现传递给Thread对象。像这样:

class MyRunnable implements Runnable {
    public void run(){
        // code to be done in thread
    }
}

Thread thread1 = new Thread(MyRunnable);
thread1.start();

修改
避免延长线程的理由 经验法则是尽可能少的耦合。继承是类之间非常强大的连接。如果要更改其某些默认行为(即重写某些方法)或想要访问Thread类的某些受保护字段,则必须从Thread继承。如果你不想要它,你选择更宽松的耦合 - 实现Runnable并将它作为构造函数参数传递给Thread实例。

答案 1 :(得分:2)

Runnable个实例传递给CyclicBarrier的构造函数。

CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() {

    @Override
    public void run() {
        System.out.println("Should wait till both threads finish executing before printing this");
    }
});

new mythread(barrier).start();
new mythread(barrier).start();

答案 2 :(得分:2)

您正在寻找Thread.join()方法......

thread1.join();
thread2.join();
System.out.println("Finished");

编辑:因为评论...

如果您不想永远等待,您还可以指定等待线程死亡的最大毫秒数加上纳秒数

答案 3 :(得分:1)

在这种情况下,循环屏障不是正确的选择。您必须在此处使用CountDownLatch

我假设您正在从main方法调用spawnAndWait方法。

这不起作用的原因是CyclicBarrier有2个构造函数。要执行后期操作,必须使用2参数构造函数。要记住的最重要的事情是主线程不会等待await方法;但会继续执行。但是,CyclicBarrier构造函数中指定的线程仅在所有生成的线程停在屏障处时运行(通过await方法)