【问题标题】:CountDownLatch in Java need additional synchronization?Java中的CountDownLatch需要额外的同步吗?
【发布时间】:2021-04-15 17:22:36
【问题描述】:

假设我有以下代码:

public class CountDownLatchExample {  // Note : Exception handling ommited
    void main(){
        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch doneSignal = new CountDownLatch(N_PARTIES);
        for(int i = 0; i < N_PARTIES; i++){ // create and start threads
            new Thread(() -> {
                startSignal.await();    // Wait startSignal before doing Work
                doWork();
                doneSignal.countDown();
            }).start();
        }
        // (...) do something else              // Don't let run yet
        startSignal.countDown();                // Let all threads proceed
        // (...) do something else
        doneSignal.await();                     // Wait for all threads to finish
    }
}

main 线程创建并启动工作线程。在run方法中,其他线程等到main线程调用startSignal.countDown(),然后才能调用doWork()和doneSignal.countDown()

我知道一个线程调用的countDown()和从await返回的线程之间存在happens-before关系,那么如果一个线程调用doneSignal.countDown(),它所做的对所有其他线程都是可见的.

但是我的问题是run()方法是否按顺序执行,是否需要添加同步??

因为当startSignal.countDown()被调用时,所有线程都可以执行run方法,但是假设doWork()方法中有一些共享变量发生了变化,或者也简单的说同时执行run(),有可能是三个线程同时执行doWork(),然后其中两个在 doneSignal.countDown() 之前被调度,第三个调用 doneSignal.countDown()。如果其他两个线程已经执行了 doWork() 并且他们只需要调用 doneSignal.countDown(),那么在此之前发生的关系就有点没用了,因为他们没有看到第三个线程做了什么,因为他们执行了 doWork () “一起”。

【问题讨论】:

    标签: java multithreading parallel-processing synchronization countdownlatch


    【解决方案1】:

    CountDownLatch 不保证 每个mutual exclusion 对共享数据的访问,而是使用这种机制来同步——在一个等待另一个的意义上——彼此之间的并行任务。类似于Cyclic barrier 提供的功能。实际上,正如您所描述的,这就是您在代码中使用这种机制的原因;协调 main 和剩余线程的执行。

    如果 doWork() 方法包含线程之间的共享状态,它是并发修改的,那么您可能有 race-condition。因此,您需要使用例如 synchronized 子句来确保共享的互斥。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 2013-06-04
      相关资源
      最近更新 更多