线程并发工具类(二):CountDownLatch
线程并发中的工具类:CountDownLatch
-
CountDownLatch:闭锁
-
概述:
-
一个或多个线程等待其他的线程完成工作后,再执行
-
应用场景:比如启动一个框架中,将数据初始化放到单独的一个/多个线程,主线程等这些线程执行完后,在执行(将初始化工作放在主线程中会影响性能)
-
内在机制:
- 工作线程调用,里面的await(),等待"初始化"线程执行完成;
- 里面有一个计数器(CNT,一般是有初值的),一旦某个"初始化"线程完成(或完成一部分),那么就调用countDown()将CNT减去1,
- 当CNT为0的时候,工作线程继续执行
-
执行流程:
-
执行细节:
-
CNT与初始化线程是没有什么关系的,一个线程完全可以多扣几次
-
初始化线程在CNT为0的时候,这个线程完全可以继续执行
- 直接搞一个线程池,干完初始化又去干其他的事情
-
等待的线程可以有多个
-
一定要注意,CNT的设置,如果说没有扣完--->业务线程被阻塞掉了
-
-
-
代码实现:
package cn.enjoyedu.ch2.tools; import java.util.concurrent.CountDownLatch; import cn.enjoyedu.tools.SleepTools; /** *类说明:演示CountDownLatch用法, * 共5个初始化子线程,6个闭锁扣除点,扣除完毕后,主线程和业务线程才能继续执行 */ public class UseCountDownLatch { //TODO //六个闭锁点 static CountDownLatch latch = new CountDownLatch(6); //模拟初始化线程 private static class InitThread implements Runnable{ @Override public void run() { System.out.println("Thread_"+Thread.currentThread().getId() +" ready init work......"); //当初始化线程完成一个初始化操作后CNT减一;实际上可以随便减,减到0,就意味着初始化工作结束了 latch.countDown(); for(int i =0;i<2;i++) { System.out.println("Thread_"+Thread.currentThread().getId() +" ........continue do its work"); } } } //业务线程:等待latch的CNT清零 private static class BusiThread implements Runnable{ @Override public void run() { //这里业务线程就被唤醒了,意味着初始化工作结束, try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } for(int i =0;i<3;i++) { System.out.println("BusiThread_"+Thread.currentThread().getId() +" do business-----"); } } } public static void main(String[] args) throws InterruptedException { new Thread(new Runnable() { @Override public void run() { SleepTools.ms(1); System.out.println("Thread_"+Thread.currentThread().getId() +" ready init work step 1st......"); //模拟在一个线程中可以对CNT进行二次扣减 //第一次扣减 latch.countDown(); System.out.println("begin step 2nd......."); SleepTools.ms(1); System.out.println("Thread_"+Thread.currentThread().getId() +" ready init work step 2nd......"); //第二次扣减 latch.countDown(); } }).start(); new Thread(new BusiThread()).start(); for(int i=0;i<=3;i++){ Thread thread = new Thread(new InitThread()); thread.start(); } //可以让主线程也等待,意味着等待的线程可以有多个 latch.await(); System.out.println("Main do ites work........"); } }
-
运行截图:
-
转载自:https://juejin.cn/post/7067226340277092383