package com.mmall.concurrency.example.aqs; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @Slf4j public class CountDownLatchExample2 { private final static int threadCount = 200; public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); final CountDownLatch countDownLatch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { final int threadNum = i; // Thread.sleep(100); // 不能放在这里,必须要在线程池包围内才有效 exec.execute(() -> { try { test(threadNum); } catch (Exception e) { log.error("exception", e); } finally { countDownLatch.countDown(); } }); } countDownLatch.await(10, TimeUnit.MILLISECONDS); log.info("finish"); exec.shutdown(); } private static void test(int threadNum) throws Exception { Thread.sleep(100); log.info("{}", threadNum); } }
分析
countDown(计数器减1),当计数器为 0 时,则执行 await 方法后的逻辑,可以指定等待时间,比如十秒,如果超过十秒,不管countDown计数器是否为0,都会执行await后面的逻辑。
await 这里的等待时间,表示的是逻辑执行的时间,所以不能把 sleep 放在线程池循环之外。
exec.shutdown之后,线程并不会立马关闭,而是会等待当前任务执行完毕后才关闭。