CountDownLatch允许一个或则多个线程等待其他线程完成操作。

  假如我们有这样的需求:我们需要解析一个excel文件中的多个sheet,我们可以考虑使用多线程,每一个线程解析excel中的一个sheet表格,等所有的线程都完成解析之后,程序提示解析完成,输出解析结果。要实现这个需求,最简单的方式是使用Thread类的join方法,等待所有的线程都完成解析之后再提示解析完成,我们可以用一下代码完成解析:

public class ReadExcelSheetsUserThreadJoinTest {

    public static void main(String[] args) throws InterruptedException {

        Thread sheet1Thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("解析sheet1");
}
}); Thread sheet2Thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("解析sheet2");
}
}); sheet1Thread.start();
sheet2Thread.start();
sheet1Thread.join();
sheet2Thread.join();
System.out.print("所有的表格解析完成");
}
}

输出结果:

解析sheet1
解析sheet2
所有的表格解析完成

  join用于让当前执行线程等待join线程执行结束,其执行原理是不停的检查join线程是否存活,如果join线程存活,则让当前线程永远等待。代码如下,其中wait(0)表示永远等待。

while (isAlive()) {
wait();
}

  直到join线程终止后,线程的this.notifyAll()方法被调用,大家可以参考JVM源码,查看notifyAll方法被调用的过程。

  在JDK1.5之后,Java的并发包提供了CountDownLatch,CountDownLatch也可以实现线程的join功能,并且比Thread的join方法提供的功能更多,使用CountDownLatch实现上述需求的代码如下:

public class ReadExcelSheetsUseCountDownLatchTest {

    private static CountDownLatch countDownLatch = new CountDownLatch();

    public static void main(String[] args) throws InterruptedException {

        Thread sheet1Thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("解析sheet1");
countDownLatch.countDown();
}
}); Thread sheet2Thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("解析sheet2");
countDownLatch.countDown();
}
}); sheet1Thread.start();
sheet2Thread.start();
countDownLatch.await();
System.out.print("所有的表格解析完成");
} }

  CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果你想等待n个点完成,就传入n,我们调用CountDownLatch的countDown方法的时候,n就会减1,await方法会阻塞当前线程直到n变为0,由于CountDownLatch的countDown方法可以用在任何地方,因此这里的n可以是n个线程,也可以是1个线程里面的n个步骤。编程的时候只需要把CountDownLatch的引用传到线程即可。

  有时候,我们不希望执行线程一直等待下去,这个时候我们可以使用CountDownLatch的await(long time,TimeUnit unit),这个方法在特定的时间之后就不会再阻塞执行线程,当然join也有类似的重载方法。

  计数器必须大于等于0,只是等于0时候,计数器就是零,调用await方法时不会阻塞当前线程。CountDownLatch不可能重新初始化或者修改CountDownLatch对象的内部计数器的值。一个线程调用countDown方法happen-before,另外一个线程调用await方法。

Java并发工具类之CountDownLatch的更多相关文章

  1. 【Java并发工具类】CountDownLatch和CyclicBarrier

    前言 下面介绍协调让多线程步调一致的两个工具类:CountDownLatch和CyclicBarrier. CountDownLatch和CyclicBarrier的用途介绍 CountDownLat ...

  2. java 并发工具类CountDownLatch & CyclicBarrier

    一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...

  3. Java并发工具类 - CountDownLatch

    Java并发工具类 - CountDownLatch 1.简介 CountDownLatch是Java1.5之后引入的Java并发工具类,放在java.util.concurrent包下面 http: ...

  4. 25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger

    1. 倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join ...

  5. Java并发工具类CountDownLatch源码中的例子

    Java并发工具类CountDownLatch源码中的例子 实例一 原文描述 /** * <p><b>Sample usage:</b> Here is a pai ...

  6. 并发工具类:CountDownLatch、CyclicBarrier、Semaphore

    在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...

  7. 基于AQS实现的Java并发工具类

    本文主要介绍一下基于AQS实现的Java并发工具类的作用,然后简单谈一下该工具类的实现原理.其实都是AQS的相关知识,只不过在AQS上包装了一下而已.本文也是基于您在有AQS的相关知识基础上,进行讲解 ...

  8. JAVA并发工具类---------------(CountDownLatch和CyclicBarrier)

    CountDownLatch是什么 CountDownLatch,英文翻译为倒计时锁存器,是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 闭锁可以延迟线程的进 ...

  9. 线程并发工具类之CountDownLatch的使用及原理分析

    原文链接:http://www.studyshare.cn/blog/details/1149/1 java开发工具下载地址及安装教程大全,点这里.更多技术文章,在这里. 一.定义 CountDown ...

随机推荐

  1. 七大排序的个人总结(二) 归并排序(Merge

    七大排序的个人总结(二)   归并排序(Merge  归并排序(Merge Sort): 归并排序是一个相当“稳定”的算法对于其它排序算法,比如希尔排序,快速排序和堆排序而言,这些算法有所谓的最好与最 ...

  2. python使用wmi模块获取windows下的系统信息监控系统-乾颐堂

    Python用WMI模块获取Windows系统的硬件信息:硬盘分区.使用情况,内存大小,CPU型号,当前运行的进程,自启动程序及位置,系统的版本等信息. 本文实例讲述了python使用wmi模块获取w ...

  3. 带你认识那些App可靠性设计

    可靠性是软件一个重要的质量属性,它关注的是软件功能持续的可用性,以及出现故障之后是否能够容错,是否能快速的恢复使用. 可靠性六条基本准则 1.故障应在第一时间被检测和感知: 2.能避免的故障都不应该发 ...

  4. FEATURE_MCT_READERDIRECT问题

    刚才查了一下,好像与一个叫CCID的驱动有关.你把FEATURE_MCT_READEDIRECT定义成0x08,再make一下试试.

  5. [SoapUI] 配置默认环境的properties

    <Envs> <Env id="Live,Default environment"> <Project> <CusProperty nam ...

  6. 2018.08.12 bzoj5301: [Cqoi2018]异或序列(前缀和+莫队)

    传送门 简单的异或前缀和处理+莫队统计答案. 惊奇的发现无论开不开long long都能跑过... 代码: #include<bits/stdc++.h> #define N 100005 ...

  7. 【Unity】1.2 HelloWorld--测试桌面和Android游戏能否正常运行

    分类:Unity.C#.VS2015 创建日期:2016-03-23 一.简介 这一节先搞一个最简单的Unity游戏,目的是为了验证Unity的桌面游戏开发环境和Android游戏开发环境是否有问题. ...

  8. =default(c++11)

    1.概念 1)如果我们需要编译器默认的行为,则可以在参数列表后面加上=default来显式地要求编译器生成合成版本的默认构造函数和拷贝控制成员:合成的默认构造函数.合成拷贝构造函数.合成拷贝赋值运算符 ...

  9. web大文件上传(web应用---SSH框架)

    版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...

  10. spring AbstractRoutingDataSource实现动态数据源切换

    使用Spring 提供的 AbstractRoutingDataSource 实现 创建 AbstractRoutingDataSource 实现类,负责保存所有数据源与切换数据源策略:public ...