java - Java 中的 CountDownLatch 需要额外的同步吗?

标签 java multithreading parallel-processing synchronization countdownlatch

假设我有以下代码:

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
    }
}

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

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

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

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

最佳答案

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

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

关于java - Java 中的 CountDownLatch 需要额外的同步吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65655480/

相关文章:

c++ - 结构、集群、服务器

ruby - 在 Ruby 哈希中并行创建键值对的问题

java - 使用JCraft Jsch - 执行sshpass命令不成功

java - 根据配置文件中的值注入(inject)依赖项

c++ - 互斥锁映射c++11

sql - 锁定选定的行,以便其他事务在读取时忽略它们

java - 在 Java 中的多线程进程中更新 boolean 值

java - 如何获取 Excel 数据并将其转换为 JSON?

java - 字符串分隔的正则表达式

.net - 空工作线程,它们是什么?