1.CyclicBarrier

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

package org.lkl.thead.foo;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 表示大家彼此等待,大家集合好后才开始出发,分散活动后又在指定地点集合碰面
*/
public class CyclicBarrierFoo {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool() ; final CyclicBarrier cyclicBarrier = new CyclicBarrier() ; //表示有3个线程需要彼此等待 都执行到 cyclicBarrier.await() ;以后才继续执行 for(int i= ;i<= ;i++){
Runnable r = new Runnable() {
@Override
public void run() { try {
Thread.sleep((long)(Math.random()*));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点1,当前已有" + (cyclicBarrier.getNumberWaiting()+) + "个已经到达," + (cyclicBarrier.getNumberWaiting()==?"都到齐了,继续走啊":"正在等候")); cyclicBarrier.await() ; //类似于集合点 Thread.sleep((long)(Math.random()*));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点2,当前已有" + (cyclicBarrier.getNumberWaiting()+) + "个已经到达," + (cyclicBarrier.getNumberWaiting()==?"都到齐了,继续走啊":"正在等候")); cyclicBarrier.await() ; //类似于集合点 Thread.sleep((long)(Math.random()*));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点3,当前已有" + (cyclicBarrier.getNumberWaiting()+) + "个已经到达," + (cyclicBarrier.getNumberWaiting()==?"都到齐了,继续走啊":"正在等候")); cyclicBarrier.await() ; //类似于集合点 } catch (Exception e) {
e.printStackTrace();
}
}
};
threadPool.execute(r) ;
}
}
}

允许结果如下:

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

2. CountdownLatchFoo

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

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

package org.lkl.thead.foo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class CountdownLatchFoo { /**
* 实现代码:
* 主线程发布命令 然后开启三个线程在等待主线程发布的命令 ,
* 当子线程接收命令以后 传递一个回调的命令给主线程 然后主线程接收回调命令
*/ public static void main(String[] args) {
final CountDownLatch orderLatch = new CountDownLatch() ; //表示从1 开始倒计时
final CountDownLatch answerLatch = new CountDownLatch() ; //表示从3开始倒计时 ExecutorService threadPool = Executors.newCachedThreadPool() ;
for(int i= ;i<= ;i++){
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("线程"+Thread.currentThread().getName()+"准备接收数据.");
try {
orderLatch.await() ; //表示等待主线程发布命令,没有接收到命令就会一致等待下去
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("线程"+Thread.currentThread().getName()+" 接收到命令 "); //只有接收到命令 程序才会从await方法中执行下来 //给主线程回调命令 System.out.println("线程"+Thread.currentThread().getName()+" 准备向主线程回调. ");
try {
Thread.sleep((long)(Math.random()*));
} catch (InterruptedException e) {
e.printStackTrace();
}
answerLatch.countDown() ; //表示发布命令 从3开始倒计时 前期主线程会被answerLatch.await() 方法拦截下来 等待回调 System.out.println("线程"+Thread.currentThread().getName()+" 已经向主线程回调. "); }
};
threadPool.execute(runnable) ;
} //主线程 try {
Thread.sleep((long)(Math.random()*));
System.out.println("主线程"+Thread.currentThread().getName()+"准备向三个子线程发送命令.");
orderLatch.countDown() ; //向三个子线程发送命令
System.out.println("主线程"+Thread.currentThread().getName()+"已经向三个子线程发送命令."); System.out.println("主线程"+Thread.currentThread().getName()+"等待三个子线程的回调.");
answerLatch.await() ; System.out.println("主线程"+Thread.currentThread().getName()+"已经收到三个子线程的回调.");
} catch (Exception e) {
e.printStackTrace();
}
}
}

运行结果:

线程pool--thread-1准备接收数据.
线程pool--thread-2准备接收数据.
线程pool--thread-3准备接收数据.
主线程main准备向三个子线程发送命令.
线程pool--thread- 接收到命令
线程pool--thread- 准备向主线程回调.
主线程main已经向三个子线程发送命令.
主线程main等待三个子线程的回调.
线程pool--thread- 接收到命令
线程pool--thread- 准备向主线程回调.
线程pool--thread- 接收到命令
线程pool--thread- 准备向主线程回调.
线程pool--thread- 已经向主线程回调.
线程pool--thread- 已经向主线程回调.
线程pool--thread- 已经向主线程回调.
主线程main已经收到三个子线程的回调.

3. Exchanger

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

package org.lkl.thead.foo;

import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class ExchangerFoo { public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool() ;
final Exchanger<String> change = new Exchanger<String>() ;
threadPool.execute(new Runnable() { @Override
public void run() {
try {
String myData = "zhangsan" ;
System.out.println("线程" + Thread.currentThread().getName() +
"正在把数据" + myData +"换出去");
String mychange = change.exchange(myData) ;
Thread.sleep((long)(Math.random()*));
System.out.println("线程" + Thread.currentThread().getName() +
"换回来的数据为" + mychange);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}) ; threadPool.execute(new Runnable() { @Override
public void run() {
try {
String myData = "lisi" ;
System.out.println("线程" + Thread.currentThread().getName() +
"正在把数据" + myData +"换出去");
String mychange = change.exchange(myData) ;
Thread.sleep((long)(Math.random()*));
System.out.println("线程" + Thread.currentThread().getName() +
"换回来的数据为" + mychange);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}) ; }
}

运行结果:

线程pool--thread-2正在把数据lisi换出去
线程pool--thread-1正在把数据zhangsan换出去
线程pool--thread-2换回来的数据为zhangsan
线程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. LVS+PIRANHA测试

    有一个知识盲点,是这个VIP,在四个服务器上都要设置? 现在只测试了两个机器,REAL SERVER没有开动. 如果LVS和REALSERVER都可以停一个作互切的话,那KEEPALIVED要它他什么 ...

  2. Intra Chroma Prediction

    帧内预测依赖于当前宏块的相邻宏块,如果任何一个相邻宏块不可用,那么会直接影响到当前宏块的预测方式. 那么宏块怎么才谓之可用? 满足以下几个条件的相邻宏块为不可用: 相邻宏块超出边界,即(x<0 ...

  3. Windows平台下主要的内存管理途径

    new / delete   malloc / free    CoTaskMemAlloc / CoTaskMemFree    IMalloc::alloc / IMalloc/free    G ...

  4. Linux下视频转换工具:转换,切割,连接,

    首先当然是需要安装ffmpeg软件包,可以直接从源中进行安装!但我安装后并不能成功执行后面所需要执行的转换命令,所以我只能重新从源码编译安装ffmpeg: (1)下载ffmpeg源码包,注意版本不能太 ...

  5. Android子线程更新主界面

    学习什么的还是要真正的有应用,有需求才能在最短的时间里面牢牢掌握一项技术. 今天就是这样的,产品一个需求下来,十万火急啊.然后之前只稍稍接触过,只能硬着头皮上了.最后牢牢地掌握了最简单的Handler ...

  6. GOTO (Transact-SQL)

    将执行流更改到标签处. 跳过 GOTO 后面的 Transact-SQL 语句,并从标签位置继续处理. GOTO 语句和标签可在过程.批处理或语句块中的任何位置使用. GOTO 语句可嵌套使用. 语法 ...

  7. HDU2056(rectangles)

    Rectangles Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. 百度2014校园招聘算法——给出一组数据A=[a_0, a_1, a-2, ... a_n](当中n可变),打印出该数值元素的全部组合。

    VC++ void StringTest(CString source, CStringArray& dest) { if(source.IsEmpty()) { } else { CStri ...

  9. HTML学习笔记之二(回到顶部 与 回究竟部)

    回到顶部 回究竟部 回到顶部的俩种方式 一.使用js $('html, body').animate({ scrollTop: 0 }, 'fast');//带动画 $('html,body').sc ...

  10. 10 Questions To Make Programming Interviews Less Expensive--reference

    Conducting Interview is not cheap and costs both time and money to a company. It take a lot of time ...