1.CyclicBarrier

表示大家彼此等待,大家集合好后才开始出发,分散活动后又在指定地点集合碰面

  1. package org.lkl.thead.foo;
  2.  
  3. import java.util.concurrent.CyclicBarrier;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6.  
  7. /**
  8. * 表示大家彼此等待,大家集合好后才开始出发,分散活动后又在指定地点集合碰面
  9. */
  10. public class CyclicBarrierFoo {
  11. public static void main(String[] args) {
  12. ExecutorService threadPool = Executors.newCachedThreadPool() ;
  13.  
  14. final CyclicBarrier cyclicBarrier = new CyclicBarrier() ; //表示有3个线程需要彼此等待 都执行到 cyclicBarrier.await() ;以后才继续执行
  15.  
  16. for(int i= ;i<= ;i++){
  17. Runnable r = new Runnable() {
  18. @Override
  19. public void run() {
  20.  
  21. try {
  22. Thread.sleep((long)(Math.random()*));
  23. System.out.println("线程" + Thread.currentThread().getName() +
  24. "即将到达集合地点1,当前已有" + (cyclicBarrier.getNumberWaiting()+) + "个已经到达," + (cyclicBarrier.getNumberWaiting()==?"都到齐了,继续走啊":"正在等候"));
  25.  
  26. cyclicBarrier.await() ; //类似于集合点
  27.  
  28. Thread.sleep((long)(Math.random()*));
  29. System.out.println("线程" + Thread.currentThread().getName() +
  30. "即将到达集合地点2,当前已有" + (cyclicBarrier.getNumberWaiting()+) + "个已经到达," + (cyclicBarrier.getNumberWaiting()==?"都到齐了,继续走啊":"正在等候"));
  31.  
  32. cyclicBarrier.await() ; //类似于集合点
  33.  
  34. Thread.sleep((long)(Math.random()*));
  35. System.out.println("线程" + Thread.currentThread().getName() +
  36. "即将到达集合地点3,当前已有" + (cyclicBarrier.getNumberWaiting()+) + "个已经到达," + (cyclicBarrier.getNumberWaiting()==?"都到齐了,继续走啊":"正在等候"));
  37.  
  38. cyclicBarrier.await() ; //类似于集合点
  39.  
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. };
  45. threadPool.execute(r) ;
  46. }
  47. }
  48. }

允许结果如下:

  1. 线程pool--thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
  2. 线程pool--thread-1即将到达集合地点1,当前已有2个已经到达,正在等候
  3. 线程pool--thread-2即将到达集合地点1,当前已有3个已经到达,都到齐了,继续走啊
  4. 线程pool--thread-3即将到达集合地点2,当前已有1个已经到达,正在等候
  5. 线程pool--thread-1即将到达集合地点2,当前已有2个已经到达,正在等候
  6. 线程pool--thread-2即将到达集合地点2,当前已有3个已经到达,都到齐了,继续走啊
  7. 线程pool--thread-2即将到达集合地点3,当前已有1个已经到达,正在等候
  8. 线程pool--thread-1即将到达集合地点3,当前已有2个已经到达,正在等候
  9. 线程pool--thread-3即将到达集合地点3,当前已有3个已经到达,都到齐了,继续走啊

2. CountdownLatchFoo

犹如倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当计数到达0时,则所有等待者或单个等待者开始执行

可以实现一个人(也可以是多个人)等待其他所有人都来通知他,这犹如一个计划需要多个领导都签字后才能继续向下实施。还可以实现一个人通知多个人的效果,类似裁判一声口令,运动员同时开始奔跑

  1. package org.lkl.thead.foo;
  2.  
  3. import java.util.concurrent.CountDownLatch;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6.  
  7. public class CountdownLatchFoo {
  8.  
  9. /**
  10. * 实现代码:
  11. * 主线程发布命令 然后开启三个线程在等待主线程发布的命令 ,
  12. * 当子线程接收命令以后 传递一个回调的命令给主线程 然后主线程接收回调命令
  13. */
  14.  
  15. public static void main(String[] args) {
  16. final CountDownLatch orderLatch = new CountDownLatch() ; //表示从1 开始倒计时
  17. final CountDownLatch answerLatch = new CountDownLatch() ; //表示从3开始倒计时
  18.  
  19. ExecutorService threadPool = Executors.newCachedThreadPool() ;
  20. for(int i= ;i<= ;i++){
  21. Runnable runnable = new Runnable() {
  22. @Override
  23. public void run() {
  24. System.out.println("线程"+Thread.currentThread().getName()+"准备接收数据.");
  25. try {
  26. orderLatch.await() ; //表示等待主线程发布命令,没有接收到命令就会一致等待下去
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30.  
  31. System.out.println("线程"+Thread.currentThread().getName()+" 接收到命令 "); //只有接收到命令 程序才会从await方法中执行下来
  32.  
  33. //给主线程回调命令
  34.  
  35. System.out.println("线程"+Thread.currentThread().getName()+" 准备向主线程回调. ");
  36. try {
  37. Thread.sleep((long)(Math.random()*));
  38. } catch (InterruptedException e) {
  39. e.printStackTrace();
  40. }
  41. answerLatch.countDown() ; //表示发布命令 从3开始倒计时 前期主线程会被answerLatch.await() 方法拦截下来 等待回调
  42.  
  43. System.out.println("线程"+Thread.currentThread().getName()+" 已经向主线程回调. ");
  44.  
  45. }
  46. };
  47. threadPool.execute(runnable) ;
  48. }
  49.  
  50. //主线程
  51.  
  52. try {
  53. Thread.sleep((long)(Math.random()*));
  54. System.out.println("主线程"+Thread.currentThread().getName()+"准备向三个子线程发送命令.");
  55. orderLatch.countDown() ; //向三个子线程发送命令
  56. System.out.println("主线程"+Thread.currentThread().getName()+"已经向三个子线程发送命令.");
  57.  
  58. System.out.println("主线程"+Thread.currentThread().getName()+"等待三个子线程的回调.");
  59. answerLatch.await() ;
  60.  
  61. System.out.println("主线程"+Thread.currentThread().getName()+"已经收到三个子线程的回调.");
  62. } catch (Exception e) {
  63. e.printStackTrace();
  64. }
  65. }
  66. }

运行结果:

  1. 线程pool--thread-1准备接收数据.
  2. 线程pool--thread-2准备接收数据.
  3. 线程pool--thread-3准备接收数据.
  4. 主线程main准备向三个子线程发送命令.
  5. 线程pool--thread- 接收到命令
  6. 线程pool--thread- 准备向主线程回调.
  7. 主线程main已经向三个子线程发送命令.
  8. 主线程main等待三个子线程的回调.
  9. 线程pool--thread- 接收到命令
  10. 线程pool--thread- 准备向主线程回调.
  11. 线程pool--thread- 接收到命令
  12. 线程pool--thread- 准备向主线程回调.
  13. 线程pool--thread- 已经向主线程回调.
  14. 线程pool--thread- 已经向主线程回调.
  15. 线程pool--thread- 已经向主线程回调.
  16. 主线程main已经收到三个子线程的回调.

3. Exchanger

用于实现两个人之间的数据交换,每个人在完成一定的事务后想与对方交换数据,第一个先拿出数据的人将一直等待第二个人拿着数据到来时,才能彼此交换数据

  1. package org.lkl.thead.foo;
  2.  
  3. import java.util.concurrent.Exchanger;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6.  
  7. public class ExchangerFoo {
  8.  
  9. public static void main(String[] args) {
  10. ExecutorService threadPool = Executors.newCachedThreadPool() ;
  11. final Exchanger<String> change = new Exchanger<String>() ;
  12. threadPool.execute(new Runnable() {
  13.  
  14. @Override
  15. public void run() {
  16. try {
  17. String myData = "zhangsan" ;
  18. System.out.println("线程" + Thread.currentThread().getName() +
  19. "正在把数据" + myData +"换出去");
  20. String mychange = change.exchange(myData) ;
  21. Thread.sleep((long)(Math.random()*));
  22. System.out.println("线程" + Thread.currentThread().getName() +
  23. "换回来的数据为" + mychange);
  24. } catch (Exception e) {
  25. // TODO Auto-generated catch block
  26. e.printStackTrace();
  27. }
  28.  
  29. }
  30. }) ;
  31.  
  32. threadPool.execute(new Runnable() {
  33.  
  34. @Override
  35. public void run() {
  36. try {
  37. String myData = "lisi" ;
  38. System.out.println("线程" + Thread.currentThread().getName() +
  39. "正在把数据" + myData +"换出去");
  40. String mychange = change.exchange(myData) ;
  41. Thread.sleep((long)(Math.random()*));
  42. System.out.println("线程" + Thread.currentThread().getName() +
  43. "换回来的数据为" + mychange);
  44. } catch (Exception e) {
  45. // TODO Auto-generated catch block
  46. e.printStackTrace();
  47. }
  48.  
  49. }
  50. }) ;
  51.  
  52. }
  53. }

运行结果:

  1. 线程pool--thread-2正在把数据lisi换出去
  2. 线程pool--thread-1正在把数据zhangsan换出去
  3. 线程pool--thread-2换回来的数据为zhangsan
  4. 线程pool--thread-1换回来的数据为lisi

多线程12-CyclicBarrier、CountDownLatch、Exchanger的更多相关文章

  1. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

  2. java多线程系列(八)---CountDownLatch和CyclicBarrie

    CountDownLatch 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线 ...

  3. 30行自己写并发工具类(Semaphore, CyclicBarrier, CountDownLatch)是什么体验?

    30行自己写并发工具类(Semaphore, CyclicBarrier, CountDownLatch)是什么体验? 前言 在本篇文章当中首先给大家介绍三个工具Semaphore, CyclicBa ...

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

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

  5. Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

    本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是Coun ...

  6. 并发工具类的使用 CountDownLatch,CyclicBarrier,Semaphore,Exchanger

    1.CountDownLatch 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助. A CountDownLatch用给定的计数初始化. await方法阻塞,直到由于countDo ...

  7. 温故知新-多线程-forkjoin、CountDownLatch、CyclicBarrier、Semaphore用法

    Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 文章目录 摘要 forkjoin C ...

  8. Java多线程中对CountDownLatch的使用

    CountDownLatch是一个非常实用的多线程控制工具类,称之为“倒计时器”,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.用给定的计数初始化CountDownLatch,其含义 ...

  9. JUC并发工具包之CyclicBarrier & CountDownLatch的异同

    1.介绍 本文我们将比较一下CyclicBarrier和CountDownLatch并了解两者的相似与不同. 2.两者是什么 当谈到并发,将这两者概念化的去解释两者是做什么的,这其实是一件很有挑战的事 ...

随机推荐

  1. 转:Node.js异步处理CPU密集型任务的新思路

    原文来自于:http://www.infoq.com/cn/articles/new-idea-of-nodejs-asynchronous-processing-tasks?utm_source=i ...

  2. Centos6.x 64位 安装JDK

    JDK下载地址: http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk7-downloads-1880260-zhs.html ...

  3. linq 的Distinct 扩展方法.

    List<miniclass> classs = new List<miniclass>(); classs.Add(new miniclass() { token = &qu ...

  4. Red Hat TimesTen安装记录

    1:内核参数修改 # vi /etc/sysctl.conf kernel.sem= #sysctl –p 备注:此安装过程为测试环境,具体参数修改要参考TimesTen官方文档. 2:创建用户及组信 ...

  5. DC-DC转换器原理与应用

    DC/DC转换器为转变输入电压后,有效输出固定电压的电压转换器.DC/DC转换器分为三类:升压型DC/DC转换器.降压型DC/DC转换器以及升降压型DC/DC转换器.根据需求可采用三类控制.PWM控制 ...

  6. 【转】浮点格式IEEE754详解

    原文网址:http://www.cnblogs.com/zjujunge/archive/2012/09/13/2682613.html Intel聘请了最好的数值分析家来为8087FPU设计浮点数格 ...

  7. 【转】android MSM8974 上DeviceTree简介----不错

    原文网址:http://blog.csdn.net/dongwuming/article/details/12784213 简介 主要功能是不在代码中硬编码设备信息,而是用专门的文件来描述.整个系统的 ...

  8. Delphi 使用自定义消息

    Delphi 使用自定义消息   1.先用Const 定义一个常量,例如 const WM_MyMessage=WM_USER+$200; 2.在要实现的unit中定义一个私有方法 procedure ...

  9. Android Memory Leak

    线程也是造成内存泄露的一个重要的源头.线程产生内存泄露的主要原因在于线程生命周期的不可控.1.看一下下面是否存在问题 public class ThreadActivity extends Activ ...

  10. Hadoop的基本命令【转载】

    在这篇文章中,我们默认认为Hadoop环境已经由运维人员配置好直接可以使用. 假设Hadoop的安装目录HADOOP_HOME为/home/admin/hadoop. 启动与关闭 启动HADOOP 进 ...