在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...
|
"的消息。
- 然后我们启动服务器。