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

CountDownLatch

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

  1. private static void testCountDownLatch() {
  2. //创建一个CountDownLatch,计数传入2,即等待两个线程完成计数为0后可继续执行
  3. //这里注意创建必须为final 否则不能调用countDown()方法
  4. final CountDownLatch cdl = new CountDownLatch(2);
  5. //线程1开始执行
  6. new Thread(new Runnable() {
  7.  
  8. public void run() {
  9. System.out.println("线程1开始执行");
  10. try {
  11. Thread.sleep(1000);
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. System.out.println("线程1结束");
  16. //执行结束后计数减1
  17. cdl.countDown();
  18. }
  19. }).start();
  20. //线程1开始执行
  21. new Thread(new Runnable() {
  22.  
  23. public void run() {
  24. System.out.println("线程2开始执行");
  25. try {
  26. Thread.sleep(2000);
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. System.out.println("线程1结束");
  31. //执行结束后计数减1
  32. cdl.countDown();
  33. }
  34. }).start();
  35. try {
  36. //线程等待,当计数为0时,可继续执行
  37. cdl.await();
  38. } catch (InterruptedException e) {
  39. e.printStackTrace();
  40. }
  41. System.out.println("继续一下步骤");
  42.  
  43. }

执行结果:

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

注意:

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

CyclicBarrier

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

  1. private static void testCyclicBarrier() {
  2. //创建一个CyclicBarrier,计数传入3,即等待两个线程完成计数为1后可继续执行
  3. final CyclicBarrier cb = new CyclicBarrier(3);
  4. //线程1开始执行
  5. new Thread(new Runnable() {
  6.  
  7. public void run() {
  8. System.out.println("线程1开始执行");
  9. try {
  10. Thread.sleep(1000);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. System.out.println("线程1结束");
  15. //遇到屏障
  16. try {
  17. cb.await();
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. } catch (BrokenBarrierException e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. }).start();
  25. //线程1开始执行
  26. new Thread(new Runnable() {
  27.  
  28. public void run() {
  29. System.out.println("线程2开始执行");
  30. try {
  31. Thread.sleep(2000);
  32. } catch (InterruptedException e) {
  33. e.printStackTrace();
  34. }
  35. System.out.println("线程2结束");
  36. //遇到屏障
  37. try {
  38. cb.await();
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. } catch (BrokenBarrierException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }).start();
  46. try {
  47. //阻塞,当计数为1时继续
  48. cb.await();
  49. } catch (InterruptedException e) {
  50. e.printStackTrace();
  51. } catch (BrokenBarrierException e) {
  52. e.printStackTrace();
  53. }
  54. System.out.println("继续一下步骤");
  55.  
  56. }

结果:同上

注意: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. jQuery中Animate进阶用法(三)

    progressType: Function( Promise animation, Number progress, Number remainingMs )每一步动画完成后调用的一个函数,无论动画 ...

  2. 20155321 2016-2017-2 《Java程序设计》第八周学习总结

    20155321 2016-2017-2 <Java程序设计>第八周学习总结 教材学习内容总结 创建Logger对象 static Logger getLogger(String name ...

  3. Linux - awk 文本处理工具四

    awk 常用示例 获取本机 IP 方式 /sbin/ifconfig |awk -v RS="Bcast:" '{print $NF}'|awk -F: '/addr/{print ...

  4. mybatis批量增加与删除——(十五)

    1.首先应该明白,mybatis增删改返回值是int型的影响行数的值 mapper接口 package cn.xm.mapper; import java.util.List; import cn.x ...

  5. linux系统时间不同步解决办法(同步本地时间)

    改变/etc/目录下的localtime文件,既可以改变当前的时区 1.方法是到/usr/share/zoneinfo目录下找到你要相对应的时区文件,例如上海在/usr/share/zoneinfo/ ...

  6. Linux的软中断处理实现 【转】

    转自:http://blog.chinaunix.net/uid-25909619-id-3070190.html 一.概念   首先我们要知道为什么中断需要下半部 .我们可以想象一下,如果没有下半部 ...

  7. linux系统下如何批量更改文件夹里面所有相同字符【转】

    如网上源码下载下来我们需要调试,调试过程中需要修改里面相同文字,下面提供三种方法供参考 通过sed命令替换 sed -i "s/oldyunwei/newyunwei/g" gre ...

  8. appium-Could not obtain screenshot: [object Object]

    原因 App页面已经被禁止截屏,禁用用户截屏的代码如下: getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); setConten ...

  9. 基于 Apache 在本地配置多个虚拟主机

    如何使用 Apache 在本地配置出多个虚拟主机呢?而且使用不同的“域名”来访问本地不同的站点呢? 一般情况下,咱们都使用 localhost 来访问本机上的服务器,在我们的 C:/WINDOWS/s ...

  10. Eclipse的git插件冲突合并方法

    Eclipse有一个git的插件叫EGit,用于实现本地代码和远程代码对比.合并以及提交.但是在本地代码和远程代码有冲突的时候,EGit的处理方案还是有点复杂.今天就彻底把这些步骤给理清楚,并公开让一 ...