有没有人能帮我理解一下JavaCountDownLatch是什么,什么时候用?

我不太清楚这个程序是如何工作的.据我所知,所有三个线程同时启动,每个线程将在3000毫秒后调用CountDownLatch.所以倒计时会一个接一个递减.闩锁归零后,程序打印"已完成".也许我理解的方式是错误的.

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Processor implements Runnable {
    private CountDownLatch latch;

    public Processor(CountDownLatch latch) {
        this.latch = latch;
    }

    public void run() {
        System.out.println("Started.");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        latch.countDown();
    }
}

// -----------------------------------------------------

public class App {

    public static void main(String[] args) {

        CountDownLatch latch = new CountDownLatch(3); // coundown from 3 to 0

        ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool

        for(int i=0; i < 3; i++) {
            executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
        }

        try {
            latch.await();  // wait until latch counted down to 0
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Completed.");
    }

}

推荐答案

是的,你理解得没错. CountDownLatch工作在锁存原理中,主线程会一直等到门打开.一个线程等待创建CountDownLatch个线程时指定的n个线程.

任何调用CountDownLatch.await()的线程,通常是应用程序的主线程,都将等待计数达到零或被另一个线程中断.所有其他线程都需要在完成或准备就绪后通过调用CountDownLatch.countDown()进行倒计时.

一旦计数达到零,等待线程就会继续.CountDownLatch的一个缺点/优点是它不可重用:一旦计数达到零,您就不能再使用CountDownLatch.

Edit:

当一个线程(如主线程)需要等待一个或多个线程完成后才能继续处理时,请使用CountDownLatch.

在Java中使用CountDownLatch的一个classic 示例是使用服务体系 struct 的服务器端核心Java应用程序,其中多个服务由多个线程提供,应用程序只有在所有服务都成功启动后才能开始处理.

附注: OP的问题有一个非常简单的例子,所以我没有包括.

Java相关问答推荐

使用SaxonJ HE在收件箱中摆脱regex

将具有多个未知字段的SON映射到Java POJO

当一个链表中间有一个循环时,它的松散部分会发生什么?

如果一个子类没有构造函数,超类也没有构造函数,那么为什么我可以构造子类的实例呢?

无法处理批处理侦听器中的反序列化异常

使用Testcontainers与OpenLiberty Server进行集成测试会抛出SocketException

Java 21虚拟线程执行器的性能比池化操作系统线程的执行器差?

如何在运行时动态创建表(使用Java、JPA、SprringBoot)

将带有js文件的 bootstrap 程序导入maven项目时出错

Java中不兼容的泛型类型

根本不显示JavaFX阿拉伯字母

是否有一个Java Future实现可以在池繁忙时在调用者线程中执行?

S数学.exp的相同错误保证也适用于StrictMath.exp吗?

如何在ImageIO或十二只猴子中旋转TIFF CMYK图像?

当我在Java中有一个Synchronized块来递增int时,必须声明一个变量Volatile吗?

IntelliJ IDEA中的JavaFX应用程序无法在资源中找到CSS文件

在Java Spring JPA中插入包含对其他实体的引用的列

Java类型推断:为什么要编译它?

让标签占用JavaFX中HBox的所有可用空间

获取月份';s在java中非UTC时区的开始时间和结束时间