java多线程开发之CyclicBarrier,CountDownLatch
最近研究了一个别人的源码,其中用到多个线程并行操作一个文件,并且在所有线程全部结束后才进行主线程后面的处理。
其用到java.util.concurrent.CyclicBarrier 这个类。
CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用,其相当于一个屏障,当一个线程跑到await()方法时,将挂起这个线程,等待直到其他线程同样跑这个await()方法。
int index = --count;
if (index == 0) { // tripped
//。。
}
else {
// We're about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
Thread.currentThread().interrupt();
}
其是使用一个计数器,当计数器没有减少到0的时候,则会将当前线程中断。
另外,这个是可以重复等待的,重复调用await()方法,将进行重新等待。
构造方法:
CyclicBarrier(int parties)
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行
当构造方法传入一个Runnable时,每次到达公共屏障点的时候都最先执行这个传进去的Runnable,然后再执行处于等待的Runnable
/**
* CyclicBarrier类似于CountDownLatch也是个计数器,
* 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数,
* 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。
* CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。
* CyclicBarrier初始时还可带一个Runnable的参数,
* 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
*/
public class CyclicBarrierTest { public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
//final CyclicBarrier cb = new CyclicBarrier(3);//创建CyclicBarrier对象并设置3个公共屏障点
final CyclicBarrier cb = new CyclicBarrier(3,new Runnable(){
@Override
public void run() {
System.out.println("********我最先执行***********");
}
});
for(int i=0;i<3;i++){
Runnable runnable = new Runnable(){
public void run(){
try {
Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行 Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await(); //这里CyclicBarrier对象又可以重用
Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
另外,其还有一些其他方法
| 方法摘要 | |
|---|---|
int |
await() 在所有 参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。 |
int |
await(long timeout, TimeUnit unit) 在所有 参与者都已经在此屏障上调用 await 方法之前,将一直等待。 |
int |
getNumberWaiting() 返回当前在屏障处等待的参与者数目。 |
int |
getParties() 返回要求启动此 barrier 的参与者数目。 |
boolean |
isBroken() 查询此屏障是否处于损坏状态。 |
void |
reset() 将屏障重置为其初始状态。 |
。。
既然提到了CyclicBarrier,就不得不提到另一个相似功能的工具类:CountDownLatch
CyclicBarrier是一个栅栏,其是将走到await()方法的线程进行拦截,直到等待全部的线程走到这个栅栏。
CountDownLatch是一个计数器,其是线程走到await()方法时,进行等待计数,将在计数到达指定值时才继续往下走。
public class CountDownLatchTest {
static CountDownLatch c = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(1);
//进行计数,计数-1
c.countDown();
System.out.println(2);
//进行计数,计数-1
c.countDown();
}
}).start();
//主线程等待计数
c.await();
System.out.println("3");
}
}
CountDownLatch当计数到0时,计数无法被重置;CyclicBarrier计数达到指定值时,计数置为0重新开始。
CountDownLatch每次调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响;
CyclicBarrier只有一个await()方法,调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞。
主要方法
public CountDownLatch(int count);
public void countDown();
public void await() throws InterruptedException
java多线程开发之CyclicBarrier,CountDownLatch的更多相关文章
- Java 多线程开发之 Callable 与线程池
前言 我们常见的创建线程的方式有 2 种:继承 Thread 和 实现 Runnable 接口. 其实,在 JDK 中还提供了另外 2 种 API 让开发者使用. 二.简单介绍 2.1 Callabl ...
- iOS多线程开发之GCD(中篇)
前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...
- iOS多线程开发之NSOperation - 快上车,没时间解释了!
一.什么是NSOperation? NSOperation是苹果提供的一套多线程解决方案.实际上NSOperation是基于GCD更高一层的封装,但是比GCD更加的面向对象.代码可读性更高.可控性更强 ...
- iOS多线程开发之NSOperation
一.什么是NSOperation? NSOperation是苹果提供的一套多线程解决方案.实际上NSOperation是基于GCD更高一层的封装,但是比GCD更加的面向对象.代码可读性更高.可控性更强 ...
- iOS多线程开发之GCD(死锁篇)
上篇和中篇讲解了什么是GCD,如何使用GCD,这篇文章将讲解使用GCD中将遇到的死锁问题.有兴趣的朋友可以回顾<iOS多线程开发之GCD(上篇)>和<iOS多线程开发之GCD(中篇) ...
- iOS多线程开发之GCD(中级篇)
前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...
- Java多线程_同步工具CountDownLatch
概念:CountDownLatch是多线程里面一个类似于计数器的高级同步工具,它的初始值代表线程的数量,当一个线程完成了任务后,CountDownLatch的值就减1,当值为0的时候,代表所有线程完成 ...
- java多线程--同步屏障CyclicBarrier的使用
CyclicBarrier的概念理解: CyclicBarrier的字面上的意思是可循环的屏障,是java并发包java.util.concurrent 里的一个同步工具类,在我下载的JDK1.6的中 ...
- java多线程等待协调工作:CountDownLatch类的高级应用
一:说明 基本上对于线程初步了解的人,都是使用synchronized来同步线程的,也确实,它也是可以满足一些常用的问题.那么我们来说一些它不能解决的问题(其实是不怎么好解决的问题,并不是真的不能解决 ...
随机推荐
- java反射的补充:桥接方法以及Spring中一些工具类
在上一篇博文中:http://www.cnblogs.com/guangshan/p/4660564.html 源码中有些地方用到了 this.bridgedMethod = BridgeMethod ...
- laravel中使用mgirations创建和迁移数据库
使用php artisan make:migration create_links_table命令 编辑2016_04_11_095342_create_links_table public func ...
- Inno Setup 通用脚本及简要说明( 一般情况够用了)
;以下脚本主要完成创建开始菜单和桌面的快捷方式,目录安装. #define MyAppName "我的软件名" #define MyAppVersion "1.0&quo ...
- 利用 StartLoadingStatus 和 FinishLoadingStatus 读取数据特别是大数据时增加渐隐渐显等待特效 - Ehlib学习(三)
代码很简单: DBGrideh.StartLoadingStatus(' Loading ... '); Sleep(500); DBGrideh.FinishLoadingStatus; 做下变动: ...
- Python【运算符】
本文介绍 1.Python运算符 运算符分类 运算符分为:算数运算.比较运算.逻辑运算.赋值运算.成员运算.身份运算.位运算 一.算数运算:返回数字 假设变量a=10,b=20 运算符: + 相加a+ ...
- Data Base Mysql迁移到SqlServer 2008工具使用方法
Data Base Mysql迁移到SqlServer 2008工具使用方法 一.下载及安装: 二.
- c# 求两个数中最大的值
1.三元运算符: class Program { static void Main(string[] args) { ,); Console.WriteLine("最大数:{0}" ...
- 忽略warning 警告
1
- 波利亚(Polya)罐子模型
(波利亚(Polya)罐子模型)罐中有a个白球,b个黑球,每次从罐中随机抽取一球,观察其颜色后,连同附加的c个同色球 (波利亚(Polya)罐子模型)罐中有a个白球,b个黑球,每次从罐中随机抽取一 ...
- “全栈2019”Java第五十六章:多态与字段详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...