• 【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;接着用户线程就会一起启动;

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

  • 相关阅读:
    泰勒综合
    滤波器、窗等的系数为什么是对称的?
    l'alphabet en francais
    弄清for循环的本质
    js中的闭包
    js中用正则表达式
    java Calendar
    Android实现XML解析技术
    junit4 详解
    redhat vi 命令
  • 原文地址:https://www.cnblogs.com/mussessein/p/11661427.html
Copyright © 2020-2023  润新知