ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### CountDownLatch CountDownLatch是闭锁的一种实现;CountDownLatch是在java1.5被引入; CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行; ``` public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); } ``` 主要API: * countDown\(\):该方法递减计数器,表示有一个事件已经发生; * await\(\):该方法等待计时器达到零,达到零后表示需要等待的所有事件都已发生; 如果计数器的值非零,await方法会一直阻塞直到计数器为零,或者等待中的线程中断,或者等待超时; ##### 起始门\(Starting Gate\) 所有子线程等待计数器为零后一起执行 ``` public class Appliction { private final static int NUM = 10; public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(1); for (int i = 0; i < NUM; i++) { new Thread(() -> { try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println(Thread.currentThread().getName() + " started:" + System.currentTimeMillis()); }).start(); } countDownLatch.countDown(); System.err.println("main thread exec end"); } } ``` ##### 结束门\(Ending Gate\) 等待所有子任务或子线程结束后\(计数器为零\),对执行结果进行统计或汇总 ``` /** * 假设有10块磁盘,需要10个线程同时统计磁盘空间大小,统计完成后由主线程进行汇总 */ public class Appliction { private final static int NUM = 10; public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(NUM); List<Disk> tasks = new ArrayList<>(NUM); for (int i = 0; i < NUM; i++) { tasks.add(new Disk()); } for (Disk dk : tasks) { new Thread(new DiskCountTask(countDownLatch, dk)).start(); } countDownLatch.await(); int size = tasks.stream().mapToInt(Disk::getSize).sum(); System.err.println("All disk space size:" + size); } } class Disk { private Integer size; public Integer getSize() { return size; } public void setSize(Integer size) { this.size = size; } } class DiskCountTask implements Runnable { private Disk disk; private CountDownLatch downLatch; public DiskCountTask(CountDownLatch downLatch, Disk disk) { this.downLatch = downLatch; this.disk = disk; } @Override public void run() { int size = new Random().nextInt(10); try { TimeUnit.SECONDS.sleep(size); } catch (InterruptedException e) { e.printStackTrace(); } disk.setSize(size); System.err.println(Thread.currentThread().getName() + " exec end[" + System.currentTimeMillis() + "], size:" + size); downLatch.countDown(); } } ``` 设想有这样一个功能需要Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给主线程去做汇总,利用CountDownLatch来完成就非常轻松