java 并发工具包 -倒计数CountDownLatch
来源:互联网 发布:淘宝开学季有什么优惠 编辑:程序博客网 时间:2024/06/10 02:47
简介
CountDownLatch 是一个同步器,翻译过来就是倒计数,意思就是用倒数来计数,当为0的时候结束。
源码分析
public class CountDownLatch { /** * 同步器,继承于aqs用来计数 */ private static final class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 4982264981922014374L; //初始化设置状态,即设置初始化计数器 Sync(int count) { setState(count); } //获取state 即获取当前的计数器 int getCount() { return getState(); }//重写父类方法,尝试判断当前值是否为0 protected int tryAcquireShared(int acquires) { return (getState() == 0) ? 1 : -1; } //重写父类方 尝试判断是否-1是否为0 protected boolean tryReleaseShared(int releases) { for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; //cas 替换state值,如果当前不匹配则循环直至state为0或者匹配成功 if (compareAndSetState(c, nextc)) return nextc == 0; } } } private final Sync sync; //初始化 其实就是去初始化sync public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); } public void await() throws InterruptedException { //如果计数器还大于0则阻塞当前线程 直到计数器=0为止 sync.acquireSharedInterruptibly(1); } //要么一直阻塞到时间过期,要么计数器=0 public boolean await(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); } //计数器-1 如果-1后=0 则释放线程 public void countDown() { sync.releaseShared(1); } //获取当前计数器 public long getCount() { return sync.getCount(); } public String toString() { return super.toString() + "[Count = " + sync.getCount() + "]"; }}
CountDownLatch源码之所以简单得易于AbstractQueuedSynchronizer 同步器,基本上所有的操作都是由AbstractQueuedSynchronizer 处理
简单例子
public class CountDownLatchTest { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(2); new Thread(new Runnable() { @Override public void run() { try { countDownLatch.await(); System.out.println("释放线程1"); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { countDownLatch.await(); System.out.println("释放线程2"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println("计数器-1"); countDownLatch.countDown(); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println("计数器-1"); countDownLatch.countDown(); } }).start(); }}
总结:
我们前面讲到CyclicBarrier同步器,两者功能类似,都是倒计数,当为0时,释放阻塞线程,但是CyclicBarrier针对的是主线程或者说一个线程,CountDownLatch针对的一组线程(上面例子中有两个线程);
CyclicBarrier可以接收Runnable参数,CountDownLatch不能;
CyclicBarrier通过执行await-1并且一直阻塞直到0大家一起接着执行,CountDownLatch通过countDown,不会阻塞;
这么说吧
CyclicBarrier :主线程和子线程最后会同时执行(如果await后面没有业务处理,和 CountDownLatch效果也类似)
CountDownLatch:一般子线程不管主线程,自己先执行掉
阅读全文
0 0
- java 并发工具包 -倒计数CountDownLatch
- java并发包之倒计数闭锁CountDownLatch
- 并发编程之倒计数闭锁CountDownLatch
- CountDownLatch倒计数锁存器
- Java并发工具包——CountDownLatch / Java并发工具包——CyclicBarrier / Java并发工具包——Semaphore / Java并发工具包——Exchanger
- [笔记][Java7并发编程实战手册]3.4 等待多个并发事件的完成CountDownLatch倒计数闭锁
- Java计数锁CountDownLatch
- JDK并发包---(9)倒计时器:CountDownLatch
- Java并发同步器--CountDownLatch
- Java并发之CountDownLatch
- Java并发之CountDownLatch
- Java并发编程:CountDownLatch
- java并发学习----CountDownLatch
- Java并发编程---CountDownLatch
- 【java并发】CountDownLatch
- JAVA 并发编程CountDownLatch
- Java多线程工具包java.util.concurrent---CountDownLatch
- Java并发工具包学习
- web前端工程化浅析
- Elasticsearch
- 接触过的前端数据结构与算法
- Elasticsearch查询——布尔查询Bool Query
- kaze算法的图像配准研究(1)-KAZE算法原理
- java 并发工具包 -倒计数CountDownLatch
- java 并发工具包 -栅栏 CyclicBarrier
- 数据结构--读书笔记一
- poj Number Sequence
- mysql连表查询时遇到的问题
- gcc命令用法总结
- 欢迎使用CSDN-markdown编辑器
- Rspec 测试基础知识
- java 并发工具包 -信号量 Semaphore