CountDownLatch源码分析
来源:互联网 发布:电话号码扫描录入软件 编辑:程序博客网 时间:2024/06/16 11:19
package java.util.concurrent;import java.util.concurrent.locks.AbstractQueuedSynchronizer;public class CountDownLatch { /** * Synchronization control For CountDownLatch. * Uses AQS state to represent count. * * 用AbstractQueuedSynchronizer的状态来表示count。 */ private static final class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 4982264981922014374L; Sync(int count) { setState(count); } int getCount() { return getState(); } protected int tryAcquireShared(int acquires) { return (getState() == 0) ? 1 : -1; } protected boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; } } } private final Sync sync;// 构造一个等待线程数量为count的闭锁。注:count的值一旦设定就不可以更改了。 public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); } /** * Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted. * * If the current count is greater than zero then the current thread becomes disabled for thread scheduling purposes * and lies dormant until one of two things happen: * The count reaches zero due to invocations of the {@link #countDown} method; * Some other thread {@linkplain Thread#interrupt interrupts} the current thread. */// 线程调用await()方法,进入等待状态。 public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); }// -------------------- 补充:AbstractQueuedSynchronizer 中的方法 ----------------------------------------////public final void acquireSharedInterruptibly(int arg) throws InterruptedException {//if (Thread.interrupted())//throw new InterruptedException();//if (tryAcquireShared(arg) < 0) // 获取锁失败//doAcquireSharedInterruptibly(arg);//}////private void doAcquireSharedInterruptibly(int arg) throws InterruptedException {// final Node node = addWaiter(Node.SHARED);// boolean failed = true;// try {// for (;;) {// 开始自旋// final Node p = node.predecessor();// if (p == head) {// int r = tryAcquireShared(arg);// if (r >= 0) {// setHeadAndPropagate(node, r);// p.next = null; // help GC// failed = false;// return;// }// }// if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())// throw new InterruptedException();// }// } finally {// if (failed) cancelAcquire(node);// }// }//// -------------------- 补充:AbstractQueuedSynchronizer 中的方法 ---------------------------------------- public boolean await(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); } /** * Decrements the count of the latch, releasing all waiting threads if the count reaches zero. * If the current count equals zero then nothing happens. */ public void countDown() { sync.releaseShared(1); }// -------------------- 补充:AbstractQueuedSynchronizer 中的方法 ----------------------------------------//// public final boolean releaseShared(int arg) {// if (tryReleaseShared(arg)) {// doReleaseShared();// return true;// }// return false;// }//// private void doReleaseShared() {// /*// * Ensure that a release propagates, even if there are other// * in-progress acquires/releases. This proceeds in the usual// * way of trying to unparkSuccessor of head if it needs// * signal. But if it does not, status is set to PROPAGATE to// * ensure that upon release, propagation continues.// * Additionally, we must loop in case a new node is added// * while we are doing this. Also, unlike other uses of// * unparkSuccessor, we need to know if CAS to reset status// * fails, if so rechecking.// */// for (;;) {// Node h = head;// if (h != null && h != tail) {// int ws = h.waitStatus;// if (ws == Node.SIGNAL) {// if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))// continue; // loop to recheck cases// unparkSuccessor(h);// }// else if (ws == 0 &&// !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))// continue; // loop on failed CAS// }// if (h == head) // loop if head changed// break;// }// }//// -------------------- 补充:AbstractQueuedSynchronizer 中的方法 ---------------------------------------- /** * Returns the current count. */ public long getCount() { return sync.getCount(); }}
阅读全文
0 0
- 《Java源码分析》:CountDownLatch
- JUC - CountDownLatch 源码分析
- 源码分析-CountDownLatch
- CountDownLatch 源码分析
- CountDownLatch源码分析
- 《Java源码分析》:CountDownLatch
- CountDownLatch源码分析
- Java源码分析之CountDownLatch
- Java 并发 --- CountDownLatch源码分析
- JUC源码分析10-locks-CountDownLatch
- Java并发之CountDownLatch源码分析
- 【Java8源码分析】并发包-CountDownLatch
- 根据AQS推测CountDownLatch及源码分析
- CountDownLatch源码
- jdk 源码分析(15)java CountDownLatch 源码解析
- CountDownLatch分析
- 分析countdownlatch
- java多线程Thread join与CountDownLatch源码分析
- SpringMVC+mybatis的配置(依赖maven)
- Ubuntu17.10下输入中文的几个小问题
- c++和java中父类指向子类的比较
- ReactNative高级---JavaScript与Native之间的通信(一)
- 从快速排序开始
- CountDownLatch源码分析
- linux二进制 八进制 十六进制之间的转换
- 20171113 输入浮点数
- tfrecord 格式理解
- linux+nginx+express+mongoose+webpack+react+react-router+sass构建web应用
- 斯坦福大学公开课IOS 7 学习笔记(2)
- SpringBoot鸡汤(各个注解集合一)
- 1646
- 逗号表达式