Java并发编程之CountDownLatch,CyclicBarrier实现一组线程相互等待、唤醒
java多线程应用场景不少,有时自己编写代码又不太容易实现,好在concurrent包提供了不少实现类,还有google的guava包更是提供了一些最佳实践,这让我们在面对一些多线程的场景时,有了不少的选择。
这里主要是看几个涉及到多线程等待的工具类。
一 CountDownLatch 一个或多个线程等待其他线程达到某一个目标后,再进行自己的下一步工作。而被等待的“其他线程”达到这个目标后,也继续自己下面的任务
public CountDownLatch(int count) { }; //参数count为计数值
public void await() throws InterruptedException { }; //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { }; //将count值减1
工作原理就是让“其他线程”在合适的地方进行await等待,直到所有线程达到了某一个目标,然后再一起释放。
import java.util.Random;
import java.util.concurrent.CountDownLatch;
/**
* Created by wuwf on 17/7/17.
* 一个线程或多个线程等待其他线程运行达到某一目标后进行自己的下一步工作,而被等待的“其他线程”达到这个目标后继续自己下面的任务。
* <p/>
*
*/
public class TestCountDownLatch {
private CountDownLatch countDownLatch = new CountDownLatch(4);
public static void main(String[] args) {
TestCountDownLatch testCountDownLatch = new TestCountDownLatch();
testCountDownLatch.begin();
}
/**
* 运动员
*/
private class Runner implements Runnable {
private int result;
public Runner(int result) {
this.result = result;
}
@Override
public void run() {
try {
//模拟跑了多少秒,1-3之间随机一个数
Thread.sleep(result * 1000);
System.out.println("运动员" + Thread.currentThread().getId() + "跑了" + result + "秒");
//跑完了就计数器减1
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void begin() {
System.out.println("赛跑开始");
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < 4; i++) {
//随机设置每个运动员跑多少秒结束
int result = random.nextInt(3) + 1;
new Thread(new Runner(result)).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有人都跑完了,裁判开始算成绩");
}
}
这段代码就是一个主线程,等待其他多个子线程完成某个任务后,再去执行下面的逻辑。
模拟并发的代码
import java.util.concurrent.CountDownLatch;
/**
* Created by wuwf on 17/7/18.
* 模拟N个线程同时启动
*/
public class TestManyThread {
private CountDownLatch countDownLatch = new CountDownLatch(200);
public static void main(String[] args) {
new TestManyThread().begin();
}
public void begin() {
for (int i = 0; i < 200; i++) {
new Thread(new UserThread()).start();
countDownLatch.countDown();
}
try {
Thread.sleep(2000);
System.out.println("线程并发");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class UserThread implements Runnable {
@Override
public void run() {
try {
//等待所有线程
countDownLatch.await();
//TODO 在这里做客户端请求,譬如访问数据库之类的操作
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
需要注意,上面两个例子是不同的方式,一个是主线程等待其他线程达到某个目标后,自己再去完成一件事;第二个例子是多个线程达到某个目标后,继续完成各自的后续任务。
其中由第二个例子引申出下一个并发工具类。
二 CyclicBarrier 实现让一组线程等待至某个状态之后再全部同时执行,而且当所有等待线程被释放后,CyclicBarrier可以被重复使用。
public CyclicBarrier(int parties, Runnable barrierAction) {
}
public CyclicBarrier(int parties) {
}
parties代表让多少个线程等待,Runnable属性是一个新线程,代表所有线程达到状态、等待完毕后,会执行的任务。
同样的也有两个await方法
public int await() throws InterruptedException, BrokenBarrierException { };
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };
第一个代表线程挂起开始等待,一直等到达到目标状态,第二个代表等待一段指定的时间后,如果还没释放,就直接继续执行,不await了。
import java.util.concurrent.CyclicBarrier;
/**
* Created by wuwf on 17/7/18.
*/
public class TestCyclicBarrier {
private CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
public static void main(String[] args) {
new TestCyclicBarrier().begin();
}
public void begin() {
for (int i = 0; i < 5; i++) {
new Thread(new Student()).start();
}
}
private class Student implements Runnable {
@Override
public void run() {
try {
System.out.println("学生" + Thread.currentThread().getId() + "正在赶往XX饭店的路上");
Thread.sleep(2000);
//到了就等着,等其他人都到了,就进饭店
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("大家都到了,进去吃饭吧!");
}
}
}
Java并发编程之CountDownLatch,CyclicBarrier实现一组线程相互等待、唤醒的更多相关文章
- Java 并发编程中的 CyclicBarrier 用于一组线程互相等待
Java 5 引入的 Concurrent 并发库软件包中的 CyclicBarrier 是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point) ...
- Java并发编程之CountDownLatch
一.场景描述 在多线程程序设计中,经常会遇到一个线程等待一个或多个线程的场景 例如:百米赛跑,十名运动员同时起跑,由于速度的快慢,肯定有先到达和后到达的,而终点有个统计成绩的仪器,当所有选手到达终点时 ...
- Java并发编程之CountDownLatch的用法
一.含义 CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能.CountDownLatch是一个同步的辅助类,它可以允许一个或多个线程等待, ...
- Java并发编程之CyclicBarrier
一.场景描述 有四个游戏玩家玩游戏,游戏有三个关卡,每个关卡必须要所有玩家都到达后才能允许通过.其实这个场景里的玩家中如果有玩家A先到了关卡1,他必须等到其他所有玩家都到达关卡1时才能通过,也就是说线 ...
- Java并发编程之CAS
CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...
- Java并发编程之CAS第一篇-什么是CAS
Java并发编程之CAS第一篇-什么是CAS 通过前面几篇的学习,我们对并发编程两个高频知识点了解了其中的一个—volatitl.从这一篇文章开始,我们将要学习另一个知识点—CAS.本篇是<凯哥 ...
- Java并发编程之CAS二源码追根溯源
Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...
- Java并发编程之CAS第三篇-CAS的缺点及解决办法
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
- Java并发编程之set集合的线程安全类你知道吗
Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥Java:kagejava)并发编程学习> ...
随机推荐
- Web服务器对比介绍
1.Apache Apache是非常强大的老牌Web服务器,具有模块化结构,拥有众多非常成熟稳定的模块,目前仍是使用非常广泛的服务器,但它是基于多进程HTTPServer,需要对每个用户请求创建一个子 ...
- 20145103《JAVA程序设计》课程总结
每周读书笔记链接汇总 假期笔记 http://www.cnblogs.com/20145103fwh/p/5248170.html 第一周读书笔记 http://www.cnblogs.com/201 ...
- 学号20145303 《Java程序设计》第一周学习总结
学号20145303 <Java程序设计>第一周学习总结 教材学习内容总结 *dos命令行: dir:列出当前目录下的文件及文件名 md:创建目录 rd:删除目录.为空时文件夹(文件夹为空 ...
- 20145314郑凯杰 《Java程序设计》第5周学习总结
20145314郑凯杰 <Java程序设计>第5周学习总结 教材学习内容总结 托管的代码: 电脑上的代码: try与catch 简单来说,try与catch是两个块,java的程序会把正常 ...
- ThinkPHP将上传问件添加到数据库
<?php namespace Home\Controller; /***************** use Think\Controller; ****命名空间****/ class Mes ...
- ubuntu环境下nginx的编译安装以及相关设置
一.基本的编译与安装 1.安装依赖项 sudo apt-get update sudo apt-get install build-essential zlib1g-dev libpcre3 libp ...
- mysql分库分表(二)
mysql分库分表 参考: https://www.cnblogs.com/dongruiha/p/6727783.html https://www.cnblogs.com/oldUncle/p/64 ...
- 【Semantic Segmentation】 Instance-sensitive Fully Convolutional Networks论文解析(转)
这篇文章比较简单,但还是不想写overview,转自: https://blog.csdn.net/zimenglan_sysu/article/details/52451098 另外,读这篇pape ...
- C++输入/输出流
2017-08-17 09:03:28 writer:pprp 基本的输入/输出流 默认情况下,输入操作会丢弃前导空白,读取数据,遇到空白的时候停止读入: 如果希望的如包括空白在内的任意字符,可以使用 ...
- HDU 1827 Summer Holiday
http://acm.hdu.edu.cn/showproblem.php?pid=1827 题意: 听说lcy帮大家预定了新马泰7日游,Wiskey真是高兴的夜不能寐啊,他想着得快点把这消息告诉大家 ...