CountDownLatch & CyclicBarrier
CountDownLatch
在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给它的代数初始化CountDownLatch,且计数器无法被重置。当前计数到达0之前,await方法一直受阻塞。
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器就减1,当计数器值到达0时,表示所有的线程以经完成了任务,然后再闭锁上等待的线程就可以恢复执行任务。
public void countDown() 递减锁存器的计数。若计数到达零,则释放所有等待的线程。若当前计数大于0,则将计数减少。若减少为0后,将重启所有等待的线程。若当前为0,则不发生任何操作。
public boolean await(long timeout, TimeUnit unit) throws InterruptedException 使当前线程在锁存器到技术至0之前一直等待。除非线程被中断或超出了指定的等待时间。若当前技术值为0,则此方法返回true。
public class Test{
public static void main(String args[]){
final CountDownLatch latch = new CountDownLatch(2);
new Thread(){
public void run(){
try{
System.out.println("子线程" + Thread.currentThread().getName() + "正在执行");
Thread.sleep(3000);
System.out.println("子线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
}catch(InterruptedException e){
e.printStackTrace();
}
};
}.start();
new Thread(){
public void run(){
try{
System.out.println("子线程" + Thread.currentThread().getName() + "正在执行");
Thread.sleep(3000);
System.out.println("子线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
}catch(InterruptedException e){
e.printStackTrace();
}
};
}.start();
}
try{
System.out.println("等待2个子线程执行完毕...");
latch.await();
System.out.println("2个子线程已经执行完毕");
System.out.println("继续执行主线程");
}catch(InterruptedException e){
e.printStackTrace();
}
}
CyclicBarrier
可循环使用的屏障。作用是让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法
CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier已经到达了屏障,然后当前线程被阻塞
CyclicBarrier的另一个构造方法是CyclicBarrier(int parites, Runnable barrierAction)用于在线程到达屏障时,优先执行barrierAction这个Runnable对象
实现原理:在CyclicBarrier内部定义了一个Lock对象,每当一个线程调用CyclicBarrier的await方法时,将剩余拦截的线程数减1,然后判断剩余拦截数是否为0,若不是,进入Lock对象的条件队列等待;若是,执行barrierAction对象的Runnable方法,然后将锁的条件队列中的所有线程放入锁等待队列,这些线程会一次获取锁,释放锁,接着从await方法返回,再从CyclicBarrier的await方法返回。
public int await() throws InterruptedException, BrokenBarrierException{
try{
return dowait(false, 0L);
}catch(TimeoutException toe){
throw new Error(toe);
}
}
private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException{
final ReentrantLock lock = this.lock;
lock.lock();
try{
final Generation g = generation;
if(g.broken){
throw new BrokenBarrierException();
}
if(Thread.interrupted()){
breakBarrier();
throw new InterruptedException();
}
int index = --count;
if(index ==0){
boolean ranAction = false;
try{
final Runnable command = barrierCommand;
if(command != null){
command.run();
}
ranAction = true;
nextGenreration();
return 0;
}finally{
if(!ranAction)
breakBarrier();
}
}
for(;;){
try{
if(!timed)
trip.await();
else if(nanos > 0L)
nanos = trip.awaitNanos(nanos);
}catch(InterruptedException ie){
if(g == generation && !g.broken){
breakBarrier();
throw ie;
}else{
Thread.currentThread().interrupt();
}
}
if(g.broken)
throw new BrokenBarrierException();
if(g != generation)
return index;
if(timed && nanos <= 0L){
breakBarrier();
throw new TimeoutException();
}
}
}finally{
lock.unlock();
}
private void breakBarrier(){
generation.broken = true;
count = parties;
trip.singalAll();
}
}
public class CyclicBarrierDemo{
private CyclicBarrier cb = new CyclicBarrier(4);
private Random random = new Random();
class Task implements Runnable{
private String id;
Task(String id){
this.id = id;
}
public void run(){
try{
Thread.sleep(random.nextInt(1000));
System.out.println("Thread " + id + " will wait");
cb.await();
System.out.println("------ Thread " + id + " is over");
}catch(InterruptedException e ){
}catch(BrokenBarrierException e){
}
}
}
public static void main(String[] args){
CyclicBarrierDemo cbd = new CyclicBarrierDemo();
ExecutorService es = Executors.newCachedThreadPool();
es.submit(cbd.new TaskDemo("a"));
es.submit(cbd.new TaskDemo("b"));
es.submit(cbd.new TaskDemo("c"));
es.submit(cbd.new TaskDemo("d"));
es.shutdown();
}
}
CyclicBarrier和CountDownLatch的区别
CyclicBarrier的计数器提供reset功能,可以多次使用。但CountDownLatch只可用一次。
CountDownLatch:一个或多个线程,等待其他多个线程完成某件事情之后才能执行
CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行
CountDownLatch & CyclicBarrier的更多相关文章
- java 并发工具类CountDownLatch & CyclicBarrier
一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...
- 并发包下常见的同步工具类详解(CountDownLatch,CyclicBarrier,Semaphore)
目录 1. 前言 2. 闭锁CountDownLatch 2.1 CountDownLatch功能简介 2.2 使用CountDownLatch 2.3 CountDownLatch原理浅析 3.循环 ...
- CountDownLatch/CyclicBarrier/Semaphore 使用过吗?
CountDownLatch/CyclicBarrier/Semaphore 使用过吗?下面详细介绍用法: 一,(等待多线程完成的)CountDownLatch 背景; countDownLatch ...
- CountDownLatch CyclicBarrier和 Semaphore
CountDownLatch CyclicBarrier和 Semaphore 原理 基于AQS实现. 让需要的暂时阻塞的线程,进入一个死循环里面,得到某个条件后再退出循环,以此实现阻塞当前线程的效果 ...
- Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...
- 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)
在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...
- CountDownLatch, CyclicBarrier and Semaphore
Reference: [1] http://shazsterblog.blogspot.co.uk/2011/12/comparison-of-countdownlatch.html CountDow ...
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- 高并发第十单:J.U.C AQS(AbstractQueuedSynchronizer) 组件:CountDownLatch. CyclicBarrier .Semaphore
这里有一篇介绍AQS的文章 非常好: Java并发之AQS详解 AQS全名:AbstractQueuedSynchronizer,是并发容器J.U.C(java.lang.concurrent)下lo ...
随机推荐
- virtualbox 中centOS在不能ssh
这个重要跟虚拟机的网络设置有关系.废话不多说. 针对一个网卡的形式.可以如下进行配置 1.网络-- 连接方式还选择“网络地址转换(NAT)” 其他不变,展开高级,设置端口转发 主机IP设为本机IP, ...
- C# 3.0 / C# 3.5 自动属性
自动属性的好处 自动属性简化了我们在做 C# 开发的时候手写一堆私有成员 + 属性的编程方式,我们只需要使用如下方式声明一个属性,编译器就会自动生成所需的成员变量. 传统属性概念 属性的目的一是封装字 ...
- 【转】MVC form提交实体接收参数时空字符串值变成null
问题:entity.BZ的值是null,Request.Form["BZ"]的值是空字符串 目标:让entity.BZ的值是空字符串. 解决方法:在实体的BZ属性上加上 [Disp ...
- Python3+selenium+BaiduAI识别并下载花瓣网高颜值妹子图片
一.说明 1.1 背景说明 上周在“Python3使用百度人脸识别接口识别高颜值妹子图片”中自己说到在成功判断颜值后,下截图片并不是什么难点. 直观感觉上确实如此,你判断的这个url适不适合下载,适合 ...
- Apache支持TRACE请求漏洞处理方案
trace和get一样是http的一种请求方法,该方法的作用是回显收到的客户端请求,一般用于测试服务器运行状态是否正常. 该方法结合浏览器漏洞可能造成跨站脚本攻击.修复方法如下: 编缉/etc/htt ...
- Linux 硬件信息命令
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理CPU个数cat /proc/cpuinfo| g ...
- sys 模块
import sys #环境变量 print(sys.path) #查看已经加载的模块 print(sys.modules) #获取终端调用时的参数 print(sys.argv) #获取解释器的版本 ...
- POJ 1936 All in All 匹配, 水题 难度:0
题目 http://poj.org/problem?id=1936 题意 多组数据,每组数据有两个字符串A,B,求A是否是B的子串.(注意是子串,也就是不必在B中连续) 思路 设置计数器cnt为当前已 ...
- window有哪写事件?
onload:加载事件网页加载完毕后执行. onscroll:滚动事件. onresize:窗口缩放事件.
- U帮忙U盘启动盘制作
第一步:制作U盘启动盘前的软.硬件准备 1.准备一个U盘或内存卡(尽量使用2G以上的) 2.进入 U帮忙官网 下载最新版U盘启动盘制作工具! 3.搜索并下载ghost版系统文件存放到电脑中. 第二步: ...