7

我正在编写将产生两个线程的代码,然后使用 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

4 回答 4

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 实例。

于 2010-03-26T10:58:10.213 回答
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();
于 2010-03-26T09:47:24.990 回答
2

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

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

编辑:因为评论......

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

于 2010-03-26T10:05:23.470 回答
1

在这种情况下,循环障碍不是正确的选择。你必须CountDownLatch在这里使用。

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

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

于 2011-09-20T07:38:23.557 回答