java多线程-CyclicBarrier
- 介绍
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。
- 主要方法
//设置parties、count及barrierCommand属性。
CyclicBarrier(int):
//当await的数量到达了设定的数量后,首先执行该Runnable对象。
CyclicBarrier(int,Runnable):
//通知barrier已完成线程
await():应用场景
1:CyclicBarrier 表示大家彼此等待,大家集合好后才开始出发,分散活动后又在i指定地点集合碰面,这就好比整个公司的人员利用周末时间集体郊游一样,先各自从家出发到公司集合后,再同时出发到公园游玩,在指定地点集合后再同时开始就餐。
代码:
public class CyclicBarrierTest {
public static void main(String[] args){
ExecutorService pool = Executors.newCachedThreadPool();
final CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
for (int i = 0; i < 3; i++) {
Runnable runnable = new Runnable() {
@Override
public void run(){
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"到达地点一,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"继续出发":"继续等待"));
try {
cyclicBarrier.await();//障碍等待点
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"到达地点二,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"继续出发":"继续等待"));
try {
cyclicBarrier.await();//障碍等待点
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"到达地点三,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"人齐了出发":"继续等待"));
try {
cyclicBarrier.await();//障碍等待点
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
pool.execute(runnable);
}
pool.shutdown();
}
}
执行结果:
pool-1-thread-3到达地点一,当前等待人数为1继续等待
pool-1-thread-1到达地点一,当前等待人数为2继续等待
pool-1-thread-2到达地点一,当前等待人数为3继续出发
pool-1-thread-1到达地点二,当前等待人数为1继续等待
pool-1-thread-3到达地点二,当前等待人数为2继续等待
pool-1-thread-2到达地点二,当前等待人数为3继续出发
pool-1-thread-3到达地点三,当前等待人数为1继续等待
pool-1-thread-2到达地点三,当前等待人数为2继续等待
pool-1-thread-1到达地点三,当前等待人数为3人齐了出发
2:在某种需求中,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择CyclicBarrier了。
代码:
public class CyclicBarrierTest1 {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool();
CyclicBarrier barrier = new CyclicBarrier(5, new mainTask());
for (int i = 0; i < 5; i++) {
subTask subTask = new subTask(barrier);
threadPool.execute(subTask);
}
threadPool.shutdown();
}
}
class subTask implements Runnable{
private CyclicBarrier barrier;
public subTask(CyclicBarrier barrier) {
super();
this.barrier = barrier;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在执行");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行完毕,等待其他结果");
try {
barrier.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class mainTask implements Runnable{
@Override
public void run() {
System.out.println("总任务执行完毕");
}
}
执行结果:
pool-1-thread-2正在执行
pool-1-thread-3正在执行
pool-1-thread-1正在执行
pool-1-thread-4正在执行
pool-1-thread-5正在执行
pool-1-thread-2执行完毕,等待其他结果
pool-1-thread-5执行完毕,等待其他结果
pool-1-thread-1执行完毕,等待其他结果
pool-1-thread-4执行完毕,等待其他结果
pool-1-thread-3执行完毕,等待其他结果
总任务执行完毕
另外,CyclicBarrier是可以重用的,它可以在使用完后继续使用,这就是Cyclic(循环)的意思。
java多线程-CyclicBarrier的更多相关文章
- 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例
java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...
- Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例
概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...
- Java多线程-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier
Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-从一个错误的双重校验锁 ...
- JAVA多线程提高十:同步工具CyclicBarrier与CountDownLatch
今天继续学习其它的同步工具:CyclicBarrier与CountDownLatch 一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公 ...
- java多线程10:并发工具类CountDownLatch、CyclicBarrier和Semaphore
在JDK的并发包(java.util.concurrent下)中给开发者提供了几个非常有用的并发工具类,让用户不需要再去关心如何在并发场景下写出同时兼顾线程安全性与高效率的代码. 本文分别介绍Coun ...
- 40个Java多线程问题总结
前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”01之 框架
本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...
- Java多线程系列目录(共43篇)
最近,在研究Java多线程的内容目录,将其内容逐步整理并发布. (一) 基础篇 01. Java多线程系列--“基础篇”01之 基本概念 02. Java多线程系列--“基础篇”02之 常用的实现多线 ...
随机推荐
- 【温故而知新-Javascript】使用 Window 对象
1. 获取 Window 对象 可以用两种方式获得Window对象.正规的HTML5方式是在Document对象上使用defaultView属性.另一种是使用所有浏览器都支持的全局变量window . ...
- 【Android Demo】获取指定网页的页面源代码
1.直接上效果图 2.代码 主要就是工具类HtmlService.java: import java.io.ByteArrayOutputStream; import java.io.InputStr ...
- POJ 3255 Roadblocks --次短路径
由于次短路一定存在,则可知次短路一定是最短路中某一条边不走,然后回到最短路,而且只是一条边,两条边以上不走的话,就一定不会是次短路了(即以边换边才能使最小).所以可以枚举每一条边,算出从起点到这条边起 ...
- 用Access作为后台数据库支撑,书写一个用C#写入记录的案例
具体的步骤: 1.创建并打开一个OleDbConnection对象 2.创建插入的SQL语句 3.创建一个OleDbCommand对象 4.使用OleDbCommand对象来插入数据 5.关闭OleD ...
- AutoIT 实现Firefox上传文件
Firefox浏览器文件上传代码如下: ;upload file Func _UploadFile($file) AutoItSetOption("WinTitleMatchMode&quo ...
- java 16 -11 ArrayList存储自定义对象并增强for遍历
需求:ArrayList存储自定义对象并遍历.要求加入泛型,并用增强for遍历. A:迭代器 B:普通for C:增强for LinkedList,Vector,Colleciton,List ...
- Yii提供的Htmler助手checkboxList可自定义Checkbox输出格式
foreach($catetags as $cate){ echo Html::checkboxList('category_id','',$cate,['item'=>'customCheck ...
- 普通请求和ajax请求的区别
普通请求和ajax请求的区别? 下面的action返回一个json文件,文件内容为sts.*,data1
- poj 3352
Road Construction Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11215 Accepted: 5575 De ...
- sql 索引 填充因子(转)
和索引重建最相关的是填充因子.当创建一个新索引,或重建一个存在的索引时,你可以指定一个填充因子,它是在索引创建时索引里的数据页被填充的数量.填充因子设置为100意味着每个索引页100%填满,50%意味 ...