zoukankan      html  css  js  c++  java
  • CountDownLatch的使用方式和场景

    一.描述
      CountDownLatch是一个用来线程同步的工具,CountDownLatch会初始化一个计时器,通过countdown()方法进行计数递减,
    并在在计数器归零之前,执行到await()的线程就会进入等待,等计数器归零,等待线程就会继续执行.

    二.应用场景
    1.在N个线程执行完毕再开始执行某一线程

    public static void main(String[] args) {
            CountDownLatch countDownLatch = new CountDownLatch(2);
            new Thread(() -> {
                System.out.println("执行线程" + Thread.currentThread().getName());
                countDownLatch.countDown();
            }, "线程A").start();
            new Thread(() -> {
                System.out.println("执行线程" + Thread.currentThread().getName());
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                countDownLatch.countDown();
            }, "线程B").start();
            System.out.println(Thread.currentThread().getName() + "等待 A, B 线程");
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "线程执行结束");
        }

    执行效果:

    执行线程线程A
    main等待 A, B 线程
    执行线程线程B
    main线程执行结束

      2.让N个线程在某个条件并行执行

    public static void main(String[] args) {
            CountDownLatch countDownLatch = new CountDownLatch(1);
            //AtomicInteger计数,确认两个线程都准备好后开始并行执行
            AtomicInteger atomicInteger = new AtomicInteger();
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "线程准备完成");
                atomicInteger.incrementAndGet();
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("执行线程" + Thread.currentThread().getName());
            }, "线程A").start();
            
            new Thread(() -> {
                //本线程延迟两秒
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "线程准备完成");
                atomicInteger.incrementAndGet();
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("执行线程" + Thread.currentThread().getName());
            }, "线程B").start();
            
            while(atomicInteger.get() < 2) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            countDownLatch.countDown();
            System.out.println("A, B线程开始并行执行");
        }

    执行效果:

    线程A线程准备完成
    线程B线程准备完成
    A, B线程开始并行执行
    执行线程线程A
    执行线程线程B

     

  • 相关阅读:
    如何让百度网盘下载速度达60MB/s!
    记一次内存溢出问题的排查、分析过程及解决思路
    使用maven命令打包可执行jar方法
    java实现四则运算
    POI如何合并单元格
    我是如何从功能测试成功转型自动化测试人员的?
    Edgar:Netflix分布式系统的可视化问题诊断平台实践
    Uber的API生命周期管理平台边缘网关(Edge Gateway)的设计实践
    UBer面向领域的微服务体系架构实践
    技术团队:问题被过度的夸大小题大做,你该怎么办?
  • 原文地址:https://www.cnblogs.com/zhexuejun/p/13093571.html
Copyright © 2011-2022 走看看