正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。

CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

CountDownLatch的方法

//可中断等待
public void await() throws InterruptedException;
//等待直到超时或者中断
public boolean await(long timeout, TimeUnit unit)throws InterruptedException;
//计数器减1
public void countDown();

CountDownLatch的应用

控制线程同时执行

package main.java.study;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {

public class MapOper implements Runnable {
        
        CountDownLatch latch ;

public MapOper(CountDownLatch latch) {
            this.latch = latch;
        }

public void run() {
            try {
                
                 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                System.out.println(Thread.currentThread().getName() + "start:" + df.format(new Date()));
                
                latch.await();
                System.out.println(Thread.currentThread().getName() + "work:" + df.format(new Date()));
                
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" Sync Started!");
        }
    }

public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        CountDownLatchTest test = new CountDownLatchTest();
        
        CountDownLatch latch = new CountDownLatch(1);
        
        Thread t1 = new Thread(test.new MapOper(latch));
        Thread t2 = new Thread(test.new MapOper(latch));
        Thread t3 = new Thread(test.new MapOper(latch));
        Thread t4 = new Thread(test.new MapOper(latch));
        
        t1.setName("Thread1");
        t2.setName("Thread2");
        t3.setName("Thread3");
        t4.setName("Thread4");
        
        t1.start();
        Thread.sleep(1500);
        t2.start();
        Thread.sleep(1500);
        t3.start();
        Thread.sleep(1500);
        t4.start();
        
        
        System.out.println("thread already start, sleep for a while...");
        
        Thread.sleep(1000);
        latch.countDown();

}

}

执行结果:线程在不同时刻启动,但是等待后在同一时刻工作。

Thread1start:2019-05-25 13:24:01
Thread2start:2019-05-25 13:24:02
Thread3start:2019-05-25 13:24:04
thread already start, sleep for a while...
Thread4start:2019-05-25 13:24:05
Thread1work:2019-05-25 13:24:06
Thread1 Sync Started!
Thread2work:2019-05-25 13:24:06
Thread2 Sync Started!
Thread3work:2019-05-25 13:24:06
Thread3 Sync Started!
Thread4work:2019-05-25 13:24:06
Thread4 Sync Started!

CountDownLatch的原理

调用countDownLatch.await()方法的线程,它会处于挂起状态,直到所有的线程都执行完countDownLatch.countDown方法,最终将计数器减为0,才会被唤醒继续执行。

CountDownLatch的源码

   private static final class Sync extends AbstractQueuedSynchronizer {private static final long serialVersionUID = 4982264981922014374L;Sync(int count) {setState(count);}int getCount() {return getState();}protected int tryAcquireShared(int acquires) {//只有state为0时,才返回1,其他返回-1,小于0则 表示acquire失败。return (getState() == 0) ? 1 : -1;}protected boolean tryReleaseShared(int releases) {// Decrement count; signal when transition to zerofor (;;) {int c = getState();if (c == 0)return false;int nextc = c-1;//每次state减1if (compareAndSetState(c, nextc))return nextc == 0;}}}
    public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);}//countDown,release(1)public void countDown() {sync.releaseShared(1);}

AbstractQueuedSynchronizer相关源码参考:https://blog.csdn.net/demon7552003/article/details/90105335

CountDownLatch应用及原理相关推荐

  1. Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析

    1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...

  2. Java多线程并发控制工具CountDownLatch,实现原理及案例

    跟着作者的65节课彻底搞懂Java并发原理专栏,一步步彻底搞懂Java并发原理. 作者简介:笔名seaboat,擅长工程算法.人工智能算法.自然语言处理.架构.分布式.高并发.大数据和搜索引擎等方面的 ...

  3. AQS、Semaphore、CountDownLatch与CyclicBarrier原理及使用方法

    AQS AQS 的全称为 AbstractQueuedSynchronizer ,翻译过来的意思就是抽象队列同步器.这个类在 java.util.concurrent.locks 包下面,AQS 就是 ...

  4. java lock 信号_java各种锁(ReentrantLock,Semaphore,CountDownLatch)的实现原理

    先放结论:主要是实现AbstractQueuedSynchronizer中进入和退出函数,控制不同的进入和退出条件,实现适用于各种场景下的锁. JAVA中对于线程的同步提供了多种锁机制,比较著名的有可 ...

  5. CountDownLatch原理详解

    介绍 当你看到这篇文章的时候需要先了解AQS的原理,因为本文不涉及到AQS内部原理的讲解. CountDownLatch是一种同步辅助,让我们多个线程执行任务时,需要等待线程执行完成后,才能执行下面的 ...

  6. 抽象同步器AQS应用之-- Semaphore、CountDownLatch、CyclicBarrier的介绍

    文章目录 1. Semaphore 2. CountDownLatch 3. CyclicBarrier 1. Semaphore Semaphore字面意思是信号量,作用是控制访问特定资源的线程数目 ...

  7. AQS及其组件的核心原理

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/l6108003/article/ details/108926410 前言 JDK1.5以前只有synchronized同步锁 ...

  8. 面试官跟我扯了半小时 CountDownLatch 后,给我发 Offer?| 原力计划

    作者 | 万猫学社 责编 | 王晓曼 出品 | CSDN博客 一个长头发.穿着清爽的小姐姐,拿着一个崭新的Mac笔记本向我走来,看着来势汹汹,我心想着肯定是技术大佬吧!但是我也是一个才华横溢的人,稳住 ...

  9. 腾讯面试居然跟我扯了半小时的CountDownLatch

    文章持续更新,微信搜索「 万猫学社 」第一时间阅读. 关注后回复「 电子书 」,免费获取12本Java必读技术书籍. 一个长头发.穿着清爽的小姐姐,拿着一个崭新的Mac笔记本向我走来,看着来势汹汹,我 ...

最新文章

  1. 2018/5/1-----1987年图灵奖PPT
  2. Android中WebView加载sdcard中的html时提示:ERR_FILE_NOT_FOUND和ERR_ACCESS_DENIED
  3. 库存管理系统软件测试,药房库存管理系统模块测试用例
  4. mysql union 放弃索引_MySQL的or/in/union与索引优化
  5. 换光纤猫 ZXA10 F420
  6. 深入浅出Android:初识Intent(BMI)
  7. linux ssh连接交换机_访问SMB交换机CLI使用SSH或远程登录
  8. (35)FPGA面试题FPGA工程师努力的方向
  9. 初级web前端必会知识点:HTML部分,看看你都会吗?
  10. 艾伟_转载:扩展方法 之 基本数据篇
  11. Windows server 2012 新功能试用---- powershell 3.0 进程和服务的操作
  12. requirejs 学习笔记 0
  13. 人像处理:不要用减淡工具了!用柔光叠加去擦!加深也不如正片叠底
  14. (15)数据结构-平衡二叉树(AVL)
  15. 将图片上传到数据库 因File.Open遭遇System.UnauthorizedAccessException
  16. 使用微信同声传译插件开发一款翻译类的小程序
  17. 在PC下载微信视频号里面的视频
  18. 单片机常用芯片系列(二)——DS18B20详解
  19. 面向对象与面向过程编程的区别
  20. c++中怎么求二维数组的长度

热门文章

  1. 【教程】jQuery打造动态下滑菜单
  2. 浅谈对JavaScript闭包的理解
  3. Spring Boot 整合 Redis 实现缓存操作
  4. Vue.js——vue-resource全攻略
  5. Property #39;sqlSessionFactory#39; or #39;sqlSessionTemplate#39; are required
  6. JAVA 设计模式 观察者模式
  7. 观察者模式及c++实现
  8. “CEPH浅析”系列之七——关于CEPH的若干想法
  9. dhcp服务配置文件/etc/dhcpd.conf详解
  10. 【javascript】checkbox——类似邮箱全选功能