zoukankan      html  css  js  c++  java
  • 【JUC】CountDownLatch

    Latch:门闩。一种线程通信的方式;当程序不涉及同步,仅仅需要线程通信的时候,使用synchronize或者lock的线程通信等待唤醒机制,就显得太重了;

    这时候,可以考虑使用信号量类:CountDownLatch,cylicbarrier,semaphore

    CountDownLatch是一个多线程控制工具类。可以实现计数器的功能。

    CountDownLatch的两种应用场景:(不能实现多个线程顺序执行!)

    1. 让某线程等待其他线程执行完毕,再开始执行;

    2. 让多个线程同时开始并行执行;

    构造器:

    // 传入一个count,指定要等待的线程个数
    public CountDownLatch(int count)

    主要方法:

    // 调用await的线程会被挂起,直到count==0,才会继续执行。
    public void await(){};
    
    // 等待一定时间,count还没有为0,线程继续执行
    public boolean await(long timeout, TimeUnit unit){};
    
    // 将count值减1,一般在线程执行结束,调用此方法,代表计数器减1.
    public void countDown() {};

    第一种场景:

    让某线程,等待n个线程执行结束,再继续执行;

    创建一个Task类

    public class Task implements Runnable {
        private String name;
        private CountDownLatch latch;
        // 线程需要CountDownLatch对象
        public Task(CountDownLatch latch, String name) {
            this.latch = latch;
            this.name = name;
        }
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                System.out.println(this.name + " Over");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown(); // 执行完毕,计数器减一
            }
        }
    }

    主方法:

    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class CountDownLatchTest {
        public static void main(String[] args) throws InterruptedException {
    
            CountDownLatch latch = new CountDownLatch(3);
            Task task_A = new Task(latch, "A");
            Task task_B = new Task(latch, "B");
            Task task_C = new Task(latch, "C");
            ExecutorService executorService = Executors.newCachedThreadPool();
            executorService.submit(task_A);
            executorService.submit(task_B);
            executorService.submit(task_C);
            executorService.shutdown();
            // 挂起mian线程,等待计数器置0,也就是三个线程执行完毕。
            latch.await();
            System.out.println(Thread.currentThread().getName());
        }
    }

    运行结果:

    A Over
    B Over
    C Over
    main    // 等待三个线程执行完毕,main线程执行

    第二种场景:

    其实跟第一种,基本一样,只不过反着来;await所有的用户线程,让main线程先行,计数器减一,为0;接着用户线程就会一起启动;

    这个方式,对于并发其实没有什么用,主要用于并行的场景;真正的同时启动多个线程。

  • 相关阅读:
    时间选择器和日期选择器
    paip.c++ qt 项目工程互相引用的方法
    leetcode_question_85 Largest Rectangle in Histogram
    在VirtualBox虚拟机上采集Fedora15系统
    Oracle
    VC6.0调试大全
    oracle中的exists 和not exists 用法详解
    vi常用命令
    【虚拟化实战】容灾设计之四VPLEX
    CentOS6.3 安装配置 ant
  • 原文地址:https://www.cnblogs.com/mussessein/p/11661427.html
Copyright © 2011-2022 走看看