美文网首页并发编程
CountDownLatch并发工具类

CountDownLatch并发工具类

作者: xiaolyuh | 来源:发表于2019-06-27 15:16 被阅读18次

    作用

    CountDownLatch允许一个或多个线程等待其他线程完成操作,相当于一个加强版的join方法。

    核心方法

    CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果你想等待N个点完 成,这里就传入N。

    • countDown:负责计数器的减一
    • await:阻塞当前线程,直到CountDownLatch计数器变成零

    由于countDown方法可以用在任何地方,所以这里说的N个 点,可以是N个线程,也可以是1个线程里的N个执行步骤。用在多个线程时,只需要把这个 CountDownLatch的引用传递到线程里即可。

    示例

    启动一个主线程,需要等到其他子线程初始化完毕

    package com.xiaolyuh;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 5个初始化线程,6个扣除点,初始化完成后业务线程和住线程才能执行
     *
     * @author yuhao.wang3
     * @since 2019/6/26 15:24
     */
    public class CountDownLatchTest {
        static final CountDownLatch countDownLatch = new CountDownLatch(6);
    
        public static void main(String[] args) {
            System.out.println(Thread.currentThread().getName() + "主线程开始......");
            new Thread(new InitJob()).start();
            new Thread(new BusinessWoerk()).start();
            new Thread(new InitJob()).start();
            new Thread(new InitWoerk()).start();
            new Thread(new InitJob()).start();
            new Thread(new InitJob()).start();
    
            try {
                System.out.println(Thread.currentThread().getName() + "主线程等待初始化线程初始化完成......");
                countDownLatch.await(1, TimeUnit.MINUTES);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            sleep(5);
            System.out.println(Thread.currentThread().getName() + "主线程结束......");
        }
    
        /**
         * 一个线程一个扣减点
         */
        static class InitJob implements Runnable {
    
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "初始化任务开始。。。。。。");
                try {
                    sleep(5);
                } finally {
                    countDownLatch.countDown();
                }
                sleep(5);
                System.out.println(Thread.currentThread().getName() + "初始化任务完毕后,处理业务逻辑。。。。。。");
            }
        }
    
        /**
         * 一个线程两个扣减点
         */
        static class InitWoerk implements Runnable {
    
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "初始化工作开始第一步》》》》》");
                try {
                    sleep(5);
                } finally {
                    countDownLatch.countDown();
                }
                System.out.println(Thread.currentThread().getName() + "初始化工作开始第二步》》》》》");
                sleep(5);
                countDownLatch.countDown();
                System.out.println(Thread.currentThread().getName() + "初始化工作处理业务逻辑》》》》》");
            }
        }
    
    
        /**
         * 业务线程
         */
        static class BusinessWoerk implements Runnable {
    
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread().getName() + "初始化线程还未完成,业务线程阻塞----------");
                    countDownLatch.await(1, TimeUnit.MINUTES);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "初始化工作完成业务线程开始工作----------");
                System.out.println(Thread.currentThread().getName() + "初始化工作完成业务线程开始工作----------");
                System.out.println(Thread.currentThread().getName() + "初始化工作完成业务线程开始工作----------");
                System.out.println(Thread.currentThread().getName() + "初始化工作完成业务线程开始工作----------");
            }
        }
    
        private static void sleep(long millis) {
            try {
                Thread.sleep(millis);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    输出结果:

    main主线程开始......
    main主线程等待初始化线程初始化完成......
    Thread-0初始化任务开始。。。。。。
    Thread-1初始化线程还未完成,业务线程阻塞----------
    Thread-2初始化任务开始。。。。。。
    Thread-3初始化工作开始第一步》》》》》
    Thread-4初始化任务开始。。。。。。
    Thread-5初始化任务开始。。。。。。
    Thread-3初始化工作开始第二步》》》》》
    Thread-0初始化任务完毕后,处理业务逻辑。。。。。。
    Thread-3初始化工作处理业务逻辑》》》》》
    Thread-2初始化任务完毕后,处理业务逻辑。。。。。。
    Thread-4初始化任务完毕后,处理业务逻辑。。。。。。
    Thread-5初始化任务完毕后,处理业务逻辑。。。。。。
    Thread-1初始化工作完成业务线程开始工作----------
    Thread-1初始化工作完成业务线程开始工作----------
    Thread-1初始化工作完成业务线程开始工作----------
    Thread-1初始化工作完成业务线程开始工作----------
    main主线程结束......
    

    参考

    《java并发编程的艺术》

    源码

    https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases

    spring-boot-student-concurrent 工程

    layering-cache

    为监控而生的多级缓存框架 layering-cache这是我开源的一个多级缓存框架的实现,如果有兴趣可以看一下

    相关文章

      网友评论

        本文标题:CountDownLatch并发工具类

        本文链接:https://www.haomeiwen.com/subject/ceuccctx.html