开发过程中或多或少会遇到一个方法需要等待两个及以上线程执行结果,如此我们如何处理,这里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. numpy中的arg系列函数

    numpy中的arg系列函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 不定期更新,现学现卖 numpy中arg系列函数被经常使用,通常先进行排序然后返回原数组特定的索引. argmax ...

  2. Linux文本处理工具——Sed

    sed:数据流编辑器: awk:报告文本的生成器 sed 基本用法:(Stream EDitor) Stream 流 EDitor 编辑器 行编辑器 全屏编辑器:vi/vimsed:内存空间(模式空间 ...

  3. python3中__get__,__getattr__,__getattribute__的区别

    __get__,__getattr__和__getattribute都是访问属性的方法,但不太相同. object.__getattr__(self, name) 当一般位置找不到attribute的 ...

  4. 重启sqlserver服务 命令

    在控制台(CMD)中运行: net stop mssqlserver     net start mssqlserver

  5. jQuery1.11源码分析(3)-----Sizzle源码中的浏览器兼容性检测和处理[原创]

    上一章讲了正则表达式,这一章继续我们的前菜,浏览器兼容性处理. 先介绍一个简单的沙盒测试函数. /** * Support testing using an element * @param {Fun ...

  6. spring事务详解(一)初探讨

    一.什么是事务 维基百科:数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成.理解:事务(Transaction)是数据库区别于文件系统的重要特性之一.传 ...

  7. 字符串(string.cpp)

    字符串(string.cpp) 神TM字符串DP 题目描述: 小林和亮亮正在做一个游戏.小林随意的写出一个字符串,字符串仅由大写字母组成,然后指定一个非负整数m,亮亮可以进行至多m次操作.每次操作为交 ...

  8. printf 字符串格式

    摘自:http://www.cppblog.com/API/archive/2013/07/18/201923.html 首先 long long是C99标准新规定的.不少编译器还不支持,Micros ...

  9. synchronized和lock

    Synchronized  同步代码块 使用 monitorenter 和 moniterexit 指令实现, monitorenter指令插入到同步代码块的开始位置, moniterexit 指令插 ...

  10. hdu 1166 线段树(单点增减 区间求和)

    Sample Input1101 2 3 4 5 6 7 8 9 10Query 1 3Add 3 6Query 2 7Sub 10 2Add 6 3Query 3 10End Sample Outp ...