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)并发编程学习> ...
随机推荐
- powershell 设置环境变量 -- go 单元测试 exit status 3221225781
执行单元测试时出错 go test -run TestImage 错误提示如下: exit status 3221225781 这个错误的意思是需要加载对应的库文件找不到,加载对应的库文件就习. 但是 ...
- 20145331 《Java程序设计》第3周学习总结
20145331 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 认识对象 •对象(Object):存在的具体实体,具有明确的状态和行为 •类(Class):具有相同属性和行 ...
- Jquery10 高级事件
学习要点: 1.模拟操作 2.命名空间 3.事件委托 4.on.off 和 one jQuery 不但封装了大量常用的事件处理,还提供了不少高级事件方便开发者使用.比如模拟用户触发事件.事件委托事件. ...
- 2017ACM/ICPC广西邀请赛-重现赛 1001 A Math Problem
2017-08-31 16:48:00 writer:pprp 这个题比较容易,我用的是快速幂 写了一次就过了 题目如下: A Math Problem Time Limit: 2000/1000 M ...
- Class.forName()与newInstance()
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...
- javascript闭包和立即执行函数的作用
一.闭包——closure 先看一个闭包的例子.我们想实现一个计数器,最简单的方法就是定义一个全局变量,计数的时候将其加1.但是全局变量有风险,哪里都有可能不小心改掉它.那局部变量呢, 它只在函数内部 ...
- JavaScript设计模式与开发实践:惰性函数
Web开发中,因为浏览器之间的差异实现差异,一些嗅探工作总是不可避免的,比如我们需要在各个浏览器中能够通用事件绑定函数addEvent //一般写法 //缺点:当他每次被调用的时候都都会执行里面的if ...
- [java]Stream API——collect、reduce、orElse(x)
一.collect 1.R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) supplier:一个能创造 ...
- DML,DML,DCL,DQL
可以先看看这篇微博:http://blog.csdn.net/jiben2qingshan/article/details/7832344 http://blog.163.com/chenwenlin ...
- .Net Core 二级域名绑定到指定的控制器
在说二级域名绑定之前,先说一下.net core中的区域,关于区域这一块儿在很久之前的博客中,已经提过,详见<03-dotnet core创建区域[Areas]及后台搭建>,在这篇博客中, ...