开发过程中或多或少会遇到一个方法需要等待两个及以上线程执行结果,如此我们如何处理,这里java提供两个方法CountDownLatch 和CyclicBarrier 方法,以下依次举例说明:

CountDownLatch

CountDownLatch 是java.util.concurrent包下的一个方法,如下实例:

private static void testCountDownLatch() {
//创建一个CountDownLatch,计数传入2,即等待两个线程完成计数为0后可继续执行
//这里注意创建必须为final 否则不能调用countDown()方法
final CountDownLatch cdl = new CountDownLatch(2);
//线程1开始执行
new Thread(new Runnable() { public void run() {
System.out.println("线程1开始执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1结束");
//执行结束后计数减1
cdl.countDown();
}
}).start();
//线程1开始执行
new Thread(new Runnable() { public void run() {
System.out.println("线程2开始执行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1结束");
//执行结束后计数减1
cdl.countDown();
}
}).start();
try {
//线程等待,当计数为0时,可继续执行
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("继续一下步骤"); }

执行结果:

线程1开始执行
线程2开始执行
线程1结束
线程2结束
继续一下步骤

注意:

countDownLatch不可能重新初始化(final)或者修改CountDownLatch对象内部计数器的值(即不能再去重新计数或者添加计数)

CyclicBarrier

CyclicBarrier 同样是java.util.concurrent包下的一个方法,如下实例:

private static void testCyclicBarrier() {
//创建一个CyclicBarrier,计数传入3,即等待两个线程完成计数为1后可继续执行
final CyclicBarrier cb = new CyclicBarrier(3);
//线程1开始执行
new Thread(new Runnable() { public void run() {
System.out.println("线程1开始执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1结束");
//遇到屏障
try {
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
//线程1开始执行
new Thread(new Runnable() { public void run() {
System.out.println("线程2开始执行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程2结束");
//遇到屏障
try {
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
try {
//阻塞,当计数为1时继续
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("继续一下步骤"); }

结果:同上

注意:CyclicBarrier 传递计数要比线程多一个(这里我也不知道为啥,具体感兴趣可以看源码,大体应该为需要await()3次,每次计数减1,当计数为0时可以继续执行),提供reset()方法重置,可处理更为复杂的逻辑

两个或多个线程执行完成之后继续执行之后的步骤,CountDownLatch与CyclicBarrier的更多相关文章

  1. Java 如何实现线程间通信?(notify、join、CountdownLatch、CyclicBarrier、FutureTask、Callable )

    转自:https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247486499&idx=1&sn=d3f2d6959df ...

  2. 死磕 java线程系列之线程池深入解析——普通任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...

  3. 死磕 java线程系列之线程池深入解析——定时任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:本文基于ScheduledThreadPoolExecutor定时线程池类. 简介 前面我们一起学习了普通 ...

  4. 面试官:线程池如何按照core、max、queue的执行循序去执行?(内附详细解析)

    前言 这是一个真实的面试题. 前几天一个朋友在群里分享了他刚刚面试候选者时问的问题:"线程池如何按照core.max.queue的执行循序去执行?". 我们都知道线程池中代码执行顺 ...

  5. Java如何判断线程池所有任务是否执行完毕

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Tes ...

  6. 用一个bat文件调用另外两个bat文件,当1.bat执行完后再执行2.bat

    用一个bat文件调用另外两个bat文件,当1.bat执行完后再执行2.bat 摘自:https://zhidao.baidu.com/question/492732911.html @echo off ...

  7. Java主线程在子线程执行完毕后再执行

    一.join() Thread中的join()方法就是同步,它使得线程之间由并行执行变为串行执行. public class MyJoinTest { public static void main( ...

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

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

  9. Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger

    1.Semaphore 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们可以正确.合理的使用公共资源. Semaphore当前在多线程 ...

随机推荐

  1. 使用Arraylist将数组中元素随机均等乱序分为N个子数组

    使用Arraylist将数组中元素随机均等乱序分为N个子数组 觉得有用的话,欢迎一起讨论相互学习~Follow Me 为了将数组中的元素 随机地 ,均等地, 不重复地 ,划分到N个子数组中 使用Arr ...

  2. CM记录-配置Hive on Spark

    默认hive on spark是禁用的,需要在Cloudera Manager中启用.1.登录CM界面,打开hive服务.2.单击 配置标签,查找enable hive on spark属性.3.勾选 ...

  3. 了解Linux操作系统的引导过程

    原文地址:http://os.51cto.com/art/200706/49690.htm 1.简介 Linux启动过程指的是从加电到看到shell提示的这一段时间. Linux启动的过程可以大概分为 ...

  4. 用matplotlib绘制每次交易的盈亏三角形

    用matplotlib绘制每次交易的盈亏三角形 结果: 代码: python def plot_trade_triangle(self): # plot each trade as a trade-t ...

  5. Flex 程序执行顺序!

    Flex 执行加载过程会有几个概念:preloader, SystemManager, Flex Application! flex 界面初始化时,看到的 Loading 加载条,那是 flex 自动 ...

  6. iOS手势UIGestureRecognizer的使用及手势冲突的解决办法【转】

    转自:iOS开发中的手势体系——UIGestureRecognizer分析及其子类的使用 关于手势的一篇很好的帖子,转载过来免得丢失.你可能最感兴趣的是手势间的互斥处理,那么就搜索 4.手势间的互斥处 ...

  7. nmap - 网络扫描

    NMap,Network Mapper 最早是Linux下的网络扫描和嗅探工具包 网络链接扫描; nmap -PT 192.168.1.1-111 # 先ping在扫描主机开放端口 nmap -O 1 ...

  8. 洛谷 P4838 P哥破解密码 题解

    矩阵乘法 + 快速幂优化递推: 看到这个题目我们不难想到递推,题干中说3个连续的A出现在序列中是不合法的,所以可以分为三种情况: (1):序列前只有一个A,如:BA,BBA,BABA. (2):序列前 ...

  9. 移动端HTML5开发 选择方案

    如今出现了大量的CSS前端框架,但真正优秀的框架只有少数几个. 本文将会比较其中五个最佳的框架.每个框架都有自己的优点和缺点,以及具体的应用领域,你可以根据自己的具体项目需求进行选择.此外,许多选项都 ...

  10. 使用配置文件启动MongoDB

    Ubuntu 16.04 (阿里云ECS),MongoDB 4.0, 原来,已经写了10篇MongoDB的随笔了.可是,自己居然没有使用配置文件启动过MongoDB,对其更多的配置是不明白的. 昨天( ...