Java中CountDownLatch使用场景

在Java的并发API中,CountDownLatch是一个同步器,它允许一个或多个线程等待一组操作完成。

如果您正在开发一个服务器应用程序,该应用程序在开始处理请求之前需要初始化各种资源。这些资源可能是这样的:

  • 加载配置文件
  • 建立数据库连接
  • 初始化缓存
  • 启动嵌入式服务器或服务

CountDownLatch 使用给定计数进行初始化,表示释放锁存器之前必须发生的操作数。每个操作都会减少该计数。当计数达到零时,所有等待线程都将被释放,并且任何后续调用这个CountDownLatch锁存器的方法都将直接通过而不会阻塞。

以下是使用代码,完整来源

   public static void main(String[] args) throws IOException, InterruptedException {
        var server = HttpServer.create(new InetSocketAddress(8000), 0);
        server.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
        server.createContext("/hello", new GreetingsHandler());

        CountDownLatch latch = new CountDownLatch(4);

        Thread.startVirtualThread(new Task(
"Load Config", latch));
        Thread.startVirtualThread(new Task(
"Init DB Connection", latch));
        Thread.startVirtualThread(new Task(
"Init Cache", latch));
        Thread.startVirtualThread(new Task(
"Start Embedded Server", latch));

        latch.await();

        System.out.println(
"All initializations complete. Application is starting...");

        server.start();
    }
}

record Task(String name, CountDownLatch latch) implements Runnable {
    @Override
    public void run() {
        doHeavyLifting();
        System.out.println(name +
" has finished.");
        latch.countDown();
    }

    private static void doHeavyLifting() {
        try {
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

class GreetingsHandler implements HttpHandler {
    @Override
    public void handle(HttpExchange t) throws IOException {
        String response =
"Hello world!";
        t.sendResponseHeaders(200, response.length());
        OutputStream os = t.getResponseBody();
        os.write(response.getBytes());
        os.close();
    }
}

  • 在本例中,我们初始化了一个 CountDownLatch,计数为 4。
  • 然后,我们创建了四个虚拟线程。每个任务完成后都会调用锁存器Latch上的 countDown()。
  • 主线程通过调用锁存器上的 await() 来等待这些任务。
  • 当计数为零时,将显示 "所有初始化完成,应用程序正在启动......
    All initializations complete. Application is starting...
    "的消息。
  • 然后我们启动服务器。