如何在Java Multithreading中使用CountDownLatch?

有人可以帮助我了解Java是什么以及何时使用它吗?CountDownLatch

我对这个程序是如何工作的没有一个非常清楚的概念。据我所知,所有三个线程同时启动,每个线程将在3000ms后调用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.");
    }

}

答案 1

是的,您理解正确。 在闩锁原理下工作,主螺纹将等到门打开。一个线程等待 n 个线程,这些线程在创建 .CountDownLatchCountDownLatch

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

一旦计数达到零,等待线程将继续。缺点/优点之一是它不可重用:一旦计数达到零,您就不能再使用。CountDownLatchCountDownLatch

编辑:

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

在 Java 中使用的一个经典示例是使用服务体系结构的服务器端核心 Java 应用程序,其中多个服务由多个线程提供,并且在所有服务成功启动之前,应用程序无法启动处理。CountDownLatch

P.S. OP的问题有一个非常直接的例子,所以我没有包括一个。


答案 2

CountDownLatch在Java中是一种同步器,它允许人们在开始处理之前等待一个或多个s。ThreadThread

CountDownLatch在闩锁原理上工作,螺纹将等到门打开。一个线程等待创建 时指定的线程数。nCountDownLatch

例如:final CountDownLatch latch = new CountDownLatch(3);

在这里,我们将计数器设置为 3。

任何线程,通常是应用程序的主线程,其调用将等到计数达到零或被另一个中断。所有其他线程都需要在完成或准备好作业后通过调用来执行倒计时。一旦计数达到零,等待开始运行。CountDownLatch.await()ThreadCountDownLatch.countDown()Thread

此处的计数通过方法递减。CountDownLatch.countDown()

哪个调用该方法将等到初始计数达到零。Threadawait()

要使计数为零,其他线程需要调用该方法。一旦计数变为零,调用该方法的线程将恢复(开始执行)。countDown()await()

缺点是它不可重用:一旦计数变为零,它就不再可用。CountDownLatch