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

发布于 2024-08-26 20:24:11 字数 676 浏览 11 评论 0原文

我正在编写将生成两个线程的代码,然后等待它们使用 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");
  }
}

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

I am writing code that will spawn two thread and then wait for them to sync up using the CyclicBarrier class. Problem is that the cyclic barrier isn't working as expected and the main thread doesnt wait for the individual threads to finish. Here's how my code looks:

 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");
  }
}

Any idea what I am doing wrong? Or is there a better way to write these barrier synchronization methods? Please help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

左秋 2024-09-02 20:24:11

在执行主线程期间,您创建两个其他线程并告诉它们互相等待。但是你没有写任何东西让你的主线程等待它们并抱怨它不等待。顺便说

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 类的某些受保护字段,则必须从 Thread 继承。如果您不想要它,您可以选择更松散的耦合 - 实现 Runnable 并将其作为构造函数参数传递给 Thread 实例。

During execution of your main thread you create two other threads and tell them to wait for each other. But you wrote nothing to make your main thread to wait for them and complain it doesn't wait. Try

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");

BTW. Don't extend Thread class unless you have to. Implement Runnable and pass implementations to Thread objects. Like this:

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

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

EDIT
Justification for avoiding extending Thread.
The rule of thumb is as little coupling as possible. Inheritance is a very strong connection between classes. You have to inherit from Thread if you want to change some of its default behaviour (i.e. override some methods) or want to access some protected fields of class Thread. If you don't want it, you choose looser coupling - implementing Runnable and passing it as a constructor parameter to Thread instance.

梦在深巷 2024-09-02 20:24:11

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();

Pass a Runnable instance to the constructor of your CyclicBarrier like this.

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();
将军与妓 2024-09-02 20:24:11

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

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

编辑:因为注释...

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

You are looking for Thread.join() method...

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

EDIT: because of the comments...

And if you don't want to wait forever you can also specify the maximum number of milliseconds plus nanoseconds to wait for the thread to die

一个人的旅程 2024-09-02 20:24:11

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

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

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

Cyclic barrier is not the correct choice in this case. You must use CountDownLatch here.

I assume you have are invoking spawnAndWait method from the main method.

The reason this wont work is that the CyclicBarrier has 2 constructors. To perform post-operations you must use a 2 parameter constructor. The most important thing to remember is that the main thread will not wait by the await method; but will continue to execute. However the Thread specified in the CyclicBarrier constructor will only run when all spawned threads stop at the barrier(by the await method)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文