上一篇博文说到semaphore,一个增强版的synchronized,该多线程辅助工具适用于控制对资源操做或者访问的场景。如今有一张场景是,须要等各个线程都都执行完了再进行下一步的操做,好比须要批量对上传的文件进行压缩,上传十个文件,压缩成一个包,这时候,就须要等上传完十个之后再进行压缩操做,相似于阻塞,concurrent包提供了countdownLatch辅助工具。java
countdownLatch,中文翻译是门闩的意思,相似一个计数器,控制线程执行任务的时机,以组团的方式一块儿执行任务。该类会判断count计数不为0时,则呈wait状态,也就是屏障处等待,若是为0则继续执行。多线程
开启两个线程进行计数,同时主线程在wait状态,最后实现组团执行后续任务:工具
@Test public void testCountDownLatch() throws InterruptedException { CountDownLatch latch = new CountDownLatch(2); for (int i = 0; i < 2; i++) { new Thread(() -> { log.info("开始count,当前是线程:{},时间是:{}",Thread.currentThread().getName(),LocalDateTime.now()); try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } latch.countDown(); }).start(); } log.info("等待计数器count,如今是:{}", LocalDateTime.now()); latch.await(); log.info("结束计数器count,如今是:{}", LocalDateTime.now()); }
运行结果是:spa
比较复杂的使用案例线程
模拟运动员从到场准备到开跑的过程,具体代码以下:翻译
@Test public void testCountDownLatch2() throws InterruptedException { CountDownLatch comingTag = new CountDownLatch(5); CountDownLatch waitTag = new CountDownLatch(1); CountDownLatch waitRunTag = new CountDownLatch(5); CountDownLatch beginTag = new CountDownLatch(1); CountDownLatch endTag = new CountDownLatch(5); for (int i = 0; i < 5; i++) { new Thread(() -> { try { Thread.sleep(5000); log.info("{}号运动员已经入场,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); comingTag.countDown(); waitTag.await(); log.info("{}号运动员开始准备,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); Thread.sleep(3000); waitRunTag.countDown(); log.info("{}号运动员准备结束,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); beginTag.await(); log.info("{}号运动员开跑,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); Thread.sleep(2000); log.info("{}号运动员跑完了,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); endTag.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } comingTag.await(); log.info("运动员所有入场,time:{}", LocalDateTime.now()); log.info("预备口令,time:{}", LocalDateTime.now()); Thread.sleep(2000); waitTag.countDown(); waitRunTag.await(); log.info("远动员准备完毕,time:{}", LocalDateTime.now()); log.info("发令枪响,time:{}", LocalDateTime.now()); Thread.sleep(2000); beginTag.countDown(); endTag.await(); log.info("所有运动员到达终点,time:{}", LocalDateTime.now()); }
运行结果是:code