zoukankan      html  css  js  c++  java
  • 第二节: 并发编程之synchronized/Lock和AQS详解

    第一部分: synchronized

    临界资源

      在多线程并发过程中,有可能会出现多个线程同时出现访问同一个共享,可变资源的情况。这个资源可能是变量、文件、对象等。

      共享:资源可以由多个线程同时访问

      可变:资源可以在其生命周期内修改

    引发的问题:

      由于线程的过程是不可控的,所以需要采用同步机制来对协同对象可变状态的访问。

    Java 中,提供了两种方式来实现同步互斥访问:synchronized 和 Lock
    同步器的本质就是加锁

    加锁目的

          序列化访问临界资源:即在任一时刻,只能有一个线程访问临界资源,也称为 同步互斥访问

    JAVA锁体系

    JAVA线程生命状态

    synchronized原理详解

          synchronized内置锁是一种对象锁,(锁的是对象而非引用),作用粒度是对象,可以用来实现对临界资源的同步互斥访问,是可重入的。

    加锁的方式:

    1. 同步实例方法    锁是当前实例对象

    2. 同步类方法    锁是当前类对象

    3. 同步代码块     锁是括号里面的对象

    synchronized不能跨方法保证原子性,那如何实现跨方法保证? --- Unsafe类monitorenter和monitorexit来实现。

    synchronized底层原理

    synchronized是基于底层JVM内置锁实现,通过内部对象Monitor(监控器锁)实现,基于进入和退出Monitor对象实现方法和代码块同步,监视器锁的实现依赖底层操作系统的Mutex Lock(互斥锁)实现,它是一个重量级锁性能较低。
    synchronized关键字被编译成字节码后会被翻译成monitorenter 和 monitorexit 两条指令分别在同步块逻辑代码的起始位置与结束位置。

    每个同步对象都有一个自己的Monitor(监视器锁),加锁过程如下图所示:

     问题:synchronized加锁加在对象上,对象是如何记录锁状态的呢?

        -- 锁状态是被记录在每个对象的对象头(Mark Word)中.

    对象的内存布局

    HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding).
       -- 对象头:比如 hash码,对象所属的年代,对象锁,锁状态标志,偏向锁(线程)ID,偏向时间,数组长度(数组对象)等
      -- 实例数据:即创建对象时,对象中成员变量,方法等
      -- 对齐填充:对象的大小必须是8字节的整数倍

    JVM内置锁在1.5之后版本做了重大的优化

    如锁粗化(Lock Coarsening)、锁消除(Lock Elimination)、轻量级锁(Lightweight Locking)、偏向锁(Biased Locking)、适应性自旋(Adaptive Spinning)等技术来减少锁操作的开销,,内置锁的并发性能已经基本与Lock持平.

    锁粗化举例:

            ===锁粗化===》   

    锁消除举例:

     逃逸分析

    使用逃逸分析,编译器可以对代码做如下优化:

    一、同步省略。如果一个对象被发现只能从一个线程被访问到,那么对于这个对象的操作可以不考虑同步。

    二、将堆分配转化为栈分配。如果一个对象在子程序中被分配,要使指向该对象的指针永远 不会逃逸,对象可能是栈分配的候选,而不是堆分配。

    三、分离对象或标量替换。有的对象可能不需要作为一个连续的内存结构存在也可以被访问 到,那么对象的部分(或全部)可以不存储在内存,而是存储在CPU寄存器中

    在Java代码运行时,通过JVM参数可指定是否开启逃逸分析,

    -XX:+DoEscapeAnalysis : 表示开启逃逸分析 ­

    -XX:­DoEscapeAnalysis : 表示关闭逃逸分析 

    从jdk 1.7开始已经默认开始逃逸分析,如需关闭,需要指定­-XX:DoEscapeAnalysis

    public class StackAllocTest {
    
        /**
         * 进行两种测试
         * 关闭逃逸分析,同时调大堆空间,避免堆内GC的发生,如果有GC信息将会被打印出来
         * VM运行参数:-Xmx4G -Xms4G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
         *
         * 开启逃逸分析
         * VM运行参数:-Xmx4G -Xms4G -XX:+DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
         *
         * 执行main方法后
         * jps 查看进程
         * jmap -histo 进程ID
         */
    
        public static void main(String[] args) {
            long start = System.currentTimeMillis();
            for (int i = 0; i < 500000; i++) {
                alloc();
            }
            long end = System.currentTimeMillis();
            //查看执行时间
            System.out.println("cost-time " + (end - start) + " ms");
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    
    
        private static TulingStudent alloc() {
            //Jit对编译时会对代码进行 逃逸分析
            //并不是所有对象存放在堆区,有的一部分存在线程栈空间
            TulingStudent student = new TulingStudent();
            return student;
        }
    
        static class TulingStudent {
            private String name;
            private int age;
        }
    }

    关闭逃逸分析:

    关闭逃逸分析,同时调大堆空间,避免堆内GC的发生,如果有GC信息将会被打印出来  
    VM运行参数:-Xmx4G -Xms4G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

    执行结果:

    查看线程 jps

    分析进程  jmap -histo + 进程号

    打开逃逸分析:

    开启逃逸分析,同时调大堆空间,避免堆内GC的发生,如果有GC信息将会被打印出来
    VM运行参数:-Xmx4G -Xms4G -XX:+DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

     

     

     

    问题: 是不是实例对象都存放在堆区? 

    -- 不一定,如果实例对象没有线程逃逸行为,实例对象存放在堆区;如果有线程逃逸行为,则有可能部分存在线程栈中。

       如果实例对象存储在堆区,实例对象内存存在堆区,实例的引用存在栈上,实例的元数据class存放在方法区或元空间。

     

     

    轻量级锁使用场景:

     

    锁的升级过程拆分

    JVM锁的膨胀升级过程场景一:

    JVM锁的膨胀升级过程场景二:

    锁的升级过程明细如下:

    第二部分: LOCK&AQS  -- 如 独占锁:ReentrantLock  读写锁:ReentrantReadWriterLock

    AbstractQueuedSynchronizer(AQS)  同步框架器

    并发之父 Doug Lea

    Java并发编程核心在于java.concurrent.util包而juc当中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这个行为的抽象就是基于AbstractQueuedSynchronizer简称AQS,

    AQS定义了一套多线程访问共享资源的同步器框架,是一个依赖状态(state)的同步器

    Java.concurrent.util当中同步器的实现如Lock,Latch,Barrier等,都是基于AQS框架实现

    • 一般通过定义内部类Sync继承AQS
    • 将同步器所有调用都映射到Sync对应的方法

    AQS内部维护属性 volatile int state (32位)

    • state表示资源的可用状态

    State三种访问方式

    • getState()、setState()、compareAndSetState()

    AQS定义两种资源共享方式

    • Exclusive-独占,只有一个线程能执行,如ReentrantLock
    • Share-共享,多个线程可以同时执行,如Semaphore/CountDownLatch

    AQS定义两种队列

    • 同步等待队列  CLH对列(双向链表)
    • 条件等待队列

    不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS已经在顶层实现好了。

    自定义同步器实现时主要实现以下几种方法:

    • isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。
    • tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
    • tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
    • tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
    • tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false



    AQS具备特性:

    • 阻塞等待队列                  
    • 共享/独占
    • 公平/非公平
    • 可重入
    • 允许中断

    问题 : 阻塞等待队列,是如何实现的?  -- 通过魔术类 UnSafe.park() /  UnSafe.unpark()  

    AbstractQueuedSynchronizer.java 

     

    问题 : 公平和非公平锁如何实现?

    公平锁:     private ReentrantLock lock = new ReentrantLock(true);

    非公平锁:  private ReentrantLock lock = new ReentrantLock(false); 

    问题 : 共享锁和独占锁如何区分的?

    AbstractQueuedSynchronizer.java 

       

       

    问题 : AQS定义两种资源共享方式?   --- 共享  和 独占

    • Exclusive -- 独占,只有一个线程能执行,如ReentrantLock
    • share -- 共享,多个线程可以同时执行,如Semaphore / CountDownLatch

    AQS定义的两种对列 

    • 同步等待队列  CLH(双向链表)
    • 条件等待队列

    同步等待队列详解

    AQS当中的同步等待队列也称CLH队列,CLH队列是Craig、Landin、Hagersten三人发明的一种基于双向链表数据结构的队列
    是FIFO先入先出线程等待队列,Java中的CLH队列是CLH队列的一个变种,线程由原自旋机制改为阻塞机制

     条件等待队列

    Condition是一个多线程间协调通信的工具类,使得某个,或者某些线程一起等待某个条件(Condition),只有当该条件具备时,这些等待线程才会被唤醒,从而重新争夺锁。

    常见各种锁详解:

     

    可重入锁举例:

    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     *  可重入锁
     */
    public class LockTemplete {
        private Integer counter = 0;
        /**
         * 可重入锁,公平锁
         * 公平锁,
         * 非公平锁
         * 需要保证多个线程使用的是同一个锁
         *
         *
         * synchronized是否可重入?
         * 虚拟机,在ObjectMonitor.hpp定义了synchronized他怎么取重入加锁 ..。hotspot源码
         * counter +1
         * 基于AQS 去实现加锁与解锁
         */
        private ReentrantLock lock = new ReentrantLock(true);
    
        /**
         * 需要保证多个线程使用的是同一个ReentrantLock对象
         * @return
         */
        public void modifyResources(String threadName){
            System.out.println("通知《管理员》线程:--->"+threadName+"准备打水");
            //默认创建的是独占锁,排它锁;同一时刻读或者写只允许一个线程获取锁
            lock.lock();
                System.out.println("线程:--->"+threadName+"第一次加锁");
                counter++;
                System.out.println("线程:"+threadName+"打第"+counter+"桶水");
                //重入该锁,我还有一件事情要做,没做完之前不能把锁资源让出去
                lock.lock();
                System.out.println("线程:--->"+threadName+"第二次加锁");
                counter++;
                System.out.println("线程:"+threadName+"打第"+counter+"桶水");
                lock.unlock();
                System.out.println("线程:"+threadName+"释放一个锁");
            lock.unlock();
            System.out.println("线程:"+threadName+"释放一个锁");
        }
    
    
        public static void main(String[] args){
            LockTemplete tp = new LockTemplete();
    
            new Thread(()->{
                String threadName = Thread.currentThread().getName();
                tp.modifyResources(threadName);
            },"Thread A").start();
    
            new Thread(()->{
                String threadName = Thread.currentThread().getName();
                tp.modifyResources(threadName);
            },"Thread B").start();
        }
    
    }

    源码解析及中文解析:

    ReentrantLock.java 
    package com.it.edu.aqs;
    /*
     * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
     */
    
    /*
     *
     *
     *
     *
     *
     * Written by Doug Lea with assistance from members of JCP JSR-166
     * Expert Group and released to the public domain, as explained at
     * http://creativecommons.org/publicdomain/zero/1.0/
     */
    
    import java.util.Collection;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    
    /**
     * A reentrant mutual exclusion {@link Lock} with the same basic
     * behavior and semantics as the implicit monitor lock accessed using
     * {@code synchronized} methods and statements, but with extended
     * capabilities.
     *
     * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
     * successfully locking, but not yet unlocking it. A thread invoking
     * {@code lock} will return, successfully acquiring the lock, when
     * the lock is not owned by another thread. The method will return
     * immediately if the current thread already owns the lock. This can
     * be checked using methods {@link #isHeldByCurrentThread}, and {@link
     * #getHoldCount}.
     *
     * <p>The constructor for this class accepts an optional
     * <em>fairness</em> parameter.  When set {@code true}, under
     * contention, locks favor granting access to the longest-waiting
     * thread.  Otherwise this lock does not guarantee any particular
     * access order.  Programs using fair locks accessed by many threads
     * may display lower overall throughput (i.e., are slower; often much
     * slower) than those using the default setting, but have smaller
     * variances in times to obtain locks and guarantee lack of
     * starvation. Note however, that fairness of locks does not guarantee
     * fairness of thread scheduling. Thus, one of many threads using a
     * fair lock may obtain it multiple times in succession while other
     * active threads are not progressing and not currently holding the
     * lock.
     * Also note that the untimed {@link #tryLock()} method does not
     * honor the fairness setting. It will succeed if the lock
     * is available even if other threads are waiting.
     *
     * <p>It is recommended practice to <em>always</em> immediately
     * follow a call to {@code lock} with a {@code try} block, most
     * typically in a before/after construction such as:
     *
     *  <pre> {@code
     * class X {
     *   private final ReentrantLock lock = new ReentrantLock();
     *   // ...
     *
     *   public void m() {
     *     lock.lock();  // block until condition holds
     *     try {
     *       // ... method body
     *     } finally {
     *       lock.unlock()
     *     }
     *   }
     * }}</pre>
     *
     * <p>In addition to implementing the {@link Lock} interface, this
     * class defines a number of {@code public} and {@code protected}
     * methods for inspecting the state of the lock.  Some of these
     * methods are only useful for instrumentation and monitoring.
     *
     * <p>Serialization of this class behaves in the same way as built-in
     * locks: a deserialized lock is in the unlocked state, regardless of
     * its state when serialized.
     *
     * <p>This lock supports a maximum of 2147483647 recursive locks by
     * the same thread. Attempts to exceed this limit result in
     * {@link Error} throws from locking methods.
     *
     * @since 1.5
     * @author Doug Lea
     */
    public class ReentrantLock implements Lock, java.io.Serializable {
        private static final long serialVersionUID = 7373984872572414699L;
        /**
         * 内部调用AQS的动作,都基于该成员属性实现
         */
        private final Sync sync;
    
        /**
         * ReentrantLock锁同步操作的基础类Sync,继承自AQS框架.
         * 该类有两个继承类,1、NonfairSync 非公平锁,2、FairSync公平锁
         */
            abstract static class Sync extends AbstractQueuedSynchronizer {
            private static final long serialVersionUID = -5179523762034025860L;
    
            /**
             * 加锁的具体行为由子类实现
             */
            abstract void lock();
    
            /**
             * 尝试获取非公平锁
             */
            final boolean nonfairTryAcquire(int acquires) {
                //acquires = 1
                final Thread current = Thread.currentThread();
                int c = getState();
                /**
                 * 不需要判断同步队列(CLH)中是否有排队等待线程
                 * 判断state状态是否为0,不为0可以加锁
                 */
                if (c == 0) {
                    //unsafe操作,cas修改state状态
                    if (compareAndSetState(0, acquires)) {
                        //独占状态锁持有者指向当前线程
                        setExclusiveOwnerThread(current);
                        return true;
                    }
                }
                /**
                 * state状态不为0,判断锁持有者是否是当前线程,
                 * 如果是当前线程持有 则state+1
                 */
                else if (current == getExclusiveOwnerThread()) {
                    int nextc = c + acquires;
                    if (nextc < 0) // overflow
                        throw new Error("Maximum lock count exceeded");
                    setState(nextc);
                    return true;
                }
                //加锁失败
                return false;
            }
    
            /**
             * 释放锁
             */
            protected final boolean tryRelease(int releases) {
                int c = getState() - releases;
                if (Thread.currentThread() != getExclusiveOwnerThread())
                    throw new IllegalMonitorStateException();
                boolean free = false;
                if (c == 0) {
                    free = true;
                    setExclusiveOwnerThread(null);
                }
                setState(c);
                return free;
            }
    
            /**
             * 判断持有独占锁的线程是否是当前线程
             */
            protected final boolean isHeldExclusively() {
                return getExclusiveOwnerThread() == Thread.currentThread();
            }
    
            //返回条件对象
            final ConditionObject newCondition() {
                return new ConditionObject();
            }
    
    
            final Thread getOwner() {
                return getState() == 0 ? null : getExclusiveOwnerThread();
            }
    
            final int getHoldCount() {
                return isHeldExclusively() ? getState() : 0;
            }
    
            final boolean isLocked() {
                return getState() != 0;
            }
    
            /**
             * Reconstitutes the instance from a stream (that is, deserializes it).
             */
            private void readObject(java.io.ObjectInputStream s)
                    throws java.io.IOException, ClassNotFoundException {
                s.defaultReadObject();
                setState(0); // reset to unlocked state
            }
        }
    
        /**
         * 非公平锁
         */
        static final class NonfairSync extends Sync {
            private static final long serialVersionUID = 7316153563782823691L;
            /**
             * 加锁行为
             */
            final void lock() {
                /**
                 * 第一步:直接尝试加锁
                 * 与公平锁实现的加锁行为一个最大的区别在于,此处不会去判断同步队列(CLH队列)中
                 * 是否有排队等待加锁的节点,上来直接加锁(判断state是否为0,CAS修改state为1)
                 * ,并将独占锁持有者 exclusiveOwnerThread 属性指向当前线程
                 * 如果当前有人占用锁,再尝试去加一次锁
                 */
                if (compareAndSetState(0, 1))
                    setExclusiveOwnerThread(Thread.currentThread());
                else
                    //AQS定义的方法,加锁
                    acquire(1);
            }
    
            /**
             * 父类AbstractQueuedSynchronizer.acquire()中调用本方法
             */
            protected final boolean tryAcquire(int acquires) {
                return nonfairTryAcquire(acquires);
            }
        }
    
        /**
         * 公平锁
         */
        static final class FairSync extends Sync {
            private static final long serialVersionUID = -3000897897090466540L;
    
            final void lock() {
                acquire(1);
            }
    
            /**
             * 重写aqs中的方法逻辑
             * 尝试加锁,被AQS的acquire()方法调用
             */
            protected final boolean tryAcquire(int acquires) {
                final Thread current = Thread.currentThread();
                int c = getState();
                if (c == 0) {
                    /**
                     * 与非公平锁中的区别,需要先判断队列当中是否有等待的节点
                     * 如果没有则可以尝试CAS获取锁
                     */
                    if (!hasQueuedPredecessors() &&
                            compareAndSetState(0, acquires)) {
                        //独占线程指向当前线程
                        setExclusiveOwnerThread(current);
                        return true;
                    }
                }
                else if (current == getExclusiveOwnerThread()) {
                    int nextc = c + acquires;
                    if (nextc < 0)
                        throw new Error("Maximum lock count exceeded");
                    setState(nextc);
                    return true;
                }
                return false;
            }
        }
    
        /**
         * 默认构造函数,创建非公平锁对象
         */
        public ReentrantLock() {
            sync = new NonfairSync();
        }
    
        /**
         * 根据要求创建公平锁或非公平锁
         */
        public ReentrantLock(boolean fair) {
            sync = fair ? new FairSync() : new NonfairSync();
        }
    
        /**
         * 加锁
         */
        public void lock() {
            sync.lock();
        }
    
        /**
         * 尝试获去取锁,获取失败被阻塞,线程被中断直接抛出异常
         */
        public void lockInterruptibly() throws InterruptedException {
            sync.acquireInterruptibly(1);
        }
    
        /**
         * 尝试加锁
         */
        public boolean tryLock() {
            return sync.nonfairTryAcquire(1);
        }
    
        /**
         * 指定等待时间内尝试加锁
         */
        public boolean tryLock(long timeout, TimeUnit unit)
                throws InterruptedException {
            return sync.tryAcquireNanos(1, unit.toNanos(timeout));
        }
    
        /**
         * 尝试去释放锁
         */
        public void unlock() {
            sync.release(1);
        }
    
        /**
         * 返回条件对象
         */
        public Condition newCondition() {
            return sync.newCondition();
        }
    
        /**
         * 返回当前线程持有的state状态数量
         */
        public int getHoldCount() {
            return sync.getHoldCount();
        }
    
        /**
         * 查询当前线程是否持有锁
         */
        public boolean isHeldByCurrentThread() {
            return sync.isHeldExclusively();
        }
    
        /**
         * 状态表示是否被Thread加锁持有
         */
        public boolean isLocked() {
            return sync.isLocked();
        }
    
        /**
         * 是否公平锁?是返回true 否则返回 false
         */
        public final boolean isFair() {
            return sync instanceof FairSync;
        }
    
        /**
         * Returns the thread that currently owns this lock, or
         * {@code null} if not owned. When this method is called by a
         * thread that is not the owner, the return value reflects a
         * best-effort approximation of current lock status. For example,
         * the owner may be momentarily {@code null} even if there are
         * threads trying to acquire the lock but have not yet done so.
         * This method is designed to facilitate construction of
         * subclasses that provide more extensive lock monitoring
         * facilities.
         *
         * @return the owner, or {@code null} if not owned
         */
        protected Thread getOwner() {
            return sync.getOwner();
        }
    
        /**
         * 判断队列当中是否有在等待获取锁的Thread节点
         */
        public final boolean hasQueuedThreads() {
            return sync.hasQueuedThreads();
        }
    
        /**
         * 当前线程是否在同步队列中等待
         */
        public final boolean hasQueuedThread(Thread thread) {
            return sync.isQueued(thread);
        }
    
        /**
         * Returns an estimate of the number of threads waiting to
         * acquire this lock.  The value is only an estimate because the number of
         * threads may change dynamically while this method traverses
         * internal data structures.  This method is designed for use in
         * monitoring of the system state, not for synchronization
         * control.
         *
         * @return the estimated number of threads waiting for this lock
         */
        public final int getQueueLength() {
            return sync.getQueueLength();
        }
    
        /**
         * 返回Thread集合,排队中的所有节点Thread会被返回
         */
        protected Collection<Thread> getQueuedThreads() {
            return sync.getQueuedThreads();
        }
    
        /**
         * 条件队列当中是否有正在等待的节点
         */
        public boolean hasWaiters(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
        }
    
        /**
         * Returns an estimate of the number of threads waiting on the
         * given condition associated with this lock. Note that because
         * timeouts and interrupts may occur at any time, the estimate
         * serves only as an upper bound on the actual number of waiters.
         * This method is designed for use in monitoring of the system
         * state, not for synchronization control.
         *
         * @param condition the condition
         * @return the estimated number of waiting threads
         * @throws IllegalMonitorStateException if this lock is not held
         * @throws IllegalArgumentException if the given condition is
         *         not associated with this lock
         * @throws NullPointerException if the condition is null
         */
        public int getWaitQueueLength(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
        }
    
        /**
         * Returns a collection containing those threads that may be
         * waiting on the given condition associated with this lock.
         * Because the actual set of threads may change dynamically while
         * constructing this result, the returned collection is only a
         * best-effort estimate. The elements of the returned collection
         * are in no particular order.  This method is designed to
         * facilitate construction of subclasses that provide more
         * extensive condition monitoring facilities.
         *
         * @param condition the condition
         * @return the collection of threads
         * @throws IllegalMonitorStateException if this lock is not held
         * @throws IllegalArgumentException if the given condition is
         *         not associated with this lock
         * @throws NullPointerException if the condition is null
         */
        protected Collection<Thread> getWaitingThreads(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
        }
    
        /**
         * Returns a string identifying this lock, as well as its lock state.
         * The state, in brackets, includes either the String {@code "Unlocked"}
         * or the String {@code "Locked by"} followed by the
         * {@linkplain Thread#getName name} of the owning thread.
         *
         * @return a string identifying this lock, as well as its lock state
         */
        public String toString() {
            Thread o = sync.getOwner();
            return super.toString() + ((o == null) ?
                    "[Unlocked]" :
                    "[Locked by thread " + o.getName() + "]");
        }
    }
    View Code
    ReentrantReadWriteLock.java
    /*
     * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     */
    
    /*
     *
     *
     *
     *
     *
     * Written by Doug Lea with assistance from members of JCP JSR-166
     * Expert Group and released to the public domain, as explained at
     * http://creativecommons.org/publicdomain/zero/1.0/
     */
    package com.it.edu.aqs;
    import java.util.concurrent.TimeUnit;
    import java.util.Collection;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReadWriteLock;
    
    /**
     * An implementation of {@link ReadWriteLock} supporting similar
     * semantics to {@link ReentrantLock}.
     * <p>This class has the following properties:
     *
     * <ul>
     * <li><b>Acquisition order</b>
     *
     * <p>This class does not impose a reader or writer preference
     * ordering for lock access.  However, it does support an optional
     * <em>fairness</em> policy.
     *
     * <dl>
     * <dt><b><i>Non-fair mode (default)</i></b>
     * <dd>When constructed as non-fair (the default), the order of entry
     * to the read and write lock is unspecified, subject to reentrancy
     * constraints.  A nonfair lock that is continuously contended may
     * indefinitely postpone one or more reader or writer threads, but
     * will normally have higher throughput than a fair lock.
     *
     * <dt><b><i>Fair mode</i></b>
     * <dd>When constructed as fair, threads contend for entry using an
     * approximately arrival-order policy. When the currently held lock
     * is released, either the longest-waiting single writer thread will
     * be assigned the write lock, or if there is a group of reader threads
     * waiting longer than all waiting writer threads, that group will be
     * assigned the read lock.
     *
     * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
     * will block if either the write lock is held, or there is a waiting
     * writer thread. The thread will not acquire the read lock until
     * after the oldest currently waiting writer thread has acquired and
     * released the write lock. Of course, if a waiting writer abandons
     * its wait, leaving one or more reader threads as the longest waiters
     * in the queue with the write lock free, then those readers will be
     * assigned the read lock.
     *
     * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
     * will block unless both the read lock and write lock are free (which
     * implies there are no waiting threads).  (Note that the non-blocking
     * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
     * do not honor this fair setting and will immediately acquire the lock
     * if it is possible, regardless of waiting threads.)
     * <p>
     * </dl>
     *
     * <li><b>Reentrancy</b>
     *
     * <p>This lock allows both readers and writers to reacquire read or
     * write locks in the style of a {@link ReentrantLock}. Non-reentrant
     * readers are not allowed until all write locks held by the writing
     * thread have been released.
     *
     * <p>Additionally, a writer can acquire the read lock, but not
     * vice-versa.  Among other applications, reentrancy can be useful
     * when write locks are held during calls or callbacks to methods that
     * perform reads under read locks.  If a reader tries to acquire the
     * write lock it will never succeed.
     *
     * <li><b>Lock downgrading</b>
     * <p>Reentrancy also allows downgrading from the write lock to a read lock,
     * by acquiring the write lock, then the read lock and then releasing the
     * write lock. However, upgrading from a read lock to the write lock is
     * <b>not</b> possible.
     *
     * <li><b>Interruption of lock acquisition</b>
     * <p>The read lock and write lock both support interruption during lock
     * acquisition.
     *
     * <li><b>{@link Condition} support</b>
     * <p>The write lock provides a {@link Condition} implementation that
     * behaves in the same way, with respect to the write lock, as the
     * {@link Condition} implementation provided by
     * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
     * This {@link Condition} can, of course, only be used with the write lock.
     *
     * <p>The read lock does not support a {@link Condition} and
     * {@code readLock().newCondition()} throws
     * {@code UnsupportedOperationException}.
     *
     * <li><b>Instrumentation</b>
     * <p>This class supports methods to determine whether locks
     * are held or contended. These methods are designed for monitoring
     * system state, not for synchronization control.
     * </ul>
     *
     * <p>Serialization of this class behaves in the same way as built-in
     * locks: a deserialized lock is in the unlocked state, regardless of
     * its state when serialized.
     *
     * <p><b>Sample usages</b>. Here is a code sketch showing how to perform
     * lock downgrading after updating a cache (exception handling is
     * particularly tricky when handling multiple locks in a non-nested
     * fashion):
     *
     * <pre> {@code
     * class CachedData {
     *   Object data;
     *   volatile boolean cacheValid;
     *   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
     *
     *   void processCachedData() {
     *     rwl.readLock().lock();
     *     if (!cacheValid) {
     *       // Must release read lock before acquiring write lock
     *       rwl.readLock().unlock();
     *       rwl.writeLock().lock();
     *       try {
     *         // Recheck state because another thread might have
     *         // acquired write lock and changed state before we did.
     *         if (!cacheValid) {
     *           data = ...
     *           cacheValid = true;
     *         }
     *         // Downgrade by acquiring read lock before releasing write lock
     *         rwl.readLock().lock();
     *       } finally {
     *         rwl.writeLock().unlock(); // Unlock write, still hold read
     *       }
     *     }
     *
     *     try {
     *       use(data);
     *     } finally {
     *       rwl.readLock().unlock();
     *     }
     *   }
     * }}</pre>
     *
     * ReentrantReadWriteLocks can be used to improve concurrency in some
     * uses of some kinds of Collections. This is typically worthwhile
     * only when the collections are expected to be large, accessed by
     * more reader threads than writer threads, and entail operations with
     * overhead that outweighs synchronization overhead. For example, here
     * is a class using a TreeMap that is expected to be large and
     * concurrently accessed.
     *
     *  <pre> {@code
     * class RWDictionary {
     *   private final Map<String, Data> m = new TreeMap<String, Data>();
     *   private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
     *   private final Lock r = rwl.readLock();
     *   private final Lock w = rwl.writeLock();
     *
     *   public Data get(String key) {
     *     r.lock();
     *     try { return m.get(key); }
     *     finally { r.unlock(); }
     *   }
     *   public String[] allKeys() {
     *     r.lock();
     *     try { return m.keySet().toArray(); }
     *     finally { r.unlock(); }
     *   }
     *   public Data put(String key, Data value) {
     *     w.lock();
     *     try { return m.put(key, value); }
     *     finally { w.unlock(); }
     *   }
     *   public void clear() {
     *     w.lock();
     *     try { m.clear(); }
     *     finally { w.unlock(); }
     *   }
     * }}</pre>
     *
     * <h3>Implementation Notes</h3>
     *
     * <p>This lock supports a maximum of 65535 recursive write locks
     * and 65535 read locks. Attempts to exceed these limits result in
     * {@link Error} throws from locking methods.
     *
     * @since 1.5
     * @author Doug Lea
     */
    public class ReentrantReadWriteLock
            implements ReadWriteLock, java.io.Serializable {
        private static final long serialVersionUID = -6992448646407690164L;
        /** Inner class providing readlock */
        private final ReentrantReadWriteLock.ReadLock readerLock;
        /** Inner class providing writelock */
        private final ReentrantReadWriteLock.WriteLock writerLock;
        /** Performs all synchronization mechanics */
        final Sync sync;
    
        /**
         * Creates a new {@code ReentrantReadWriteLock} with
         * default (nonfair) ordering properties.
         */
        public ReentrantReadWriteLock() {
            this(false);
        }
    
        /**
         * Creates a new {@code ReentrantReadWriteLock} with
         * the given fairness policy.
         *
         * @param fair {@code true} if this lock should use a fair ordering policy
         */
        public ReentrantReadWriteLock(boolean fair) {
            sync = fair ? new FairSync() : new NonfairSync();
            readerLock = new ReadLock(this);
            writerLock = new WriteLock(this);
        }
    
        public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
        public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }
    
        /**
         * Synchronization implementation for ReentrantReadWriteLock.
         * Subclassed into fair and nonfair versions.
         */
        abstract static class Sync extends AbstractQueuedSynchronizer {
            private static final long serialVersionUID = 6317671515068378041L;
    
            /*
             * Read vs write count extraction constants and functions.
             * Lock state is logically divided into two unsigned shorts:
             * The lower one representing the exclusive (writer) lock hold count,
             * and the upper the shared (reader) hold count.
             */
    
            static final int SHARED_SHIFT   = 16;
            static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
            static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
            static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
    
            /** Returns the number of shared holds represented in count  */
            static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
            /** Returns the number of exclusive holds represented in count  */
            static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
    
            /**
             * A counter for per-thread read hold counts.
             * Maintained as a ThreadLocal; cached in cachedHoldCounter
             */
            static final class HoldCounter {
                int count = 0;
                // Use id, not reference, to avoid garbage retention
                final long tid = getThreadId(Thread.currentThread());
            }
    
            /**
             * ThreadLocal subclass. Easiest to explicitly define for sake
             * of deserialization mechanics.
             */
            static final class ThreadLocalHoldCounter
                    extends ThreadLocal<HoldCounter> {
                public HoldCounter initialValue() {
                    return new HoldCounter();
                }
            }
    
            /**
             * The number of reentrant read locks held by current thread.
             * Initialized only in constructor and readObject.
             * Removed whenever a thread's read hold count drops to 0.
             */
            private transient ThreadLocalHoldCounter readHolds;
    
            /**
             * The hold count of the last thread to successfully acquire
             * readLock. This saves ThreadLocal lookup in the common case
             * where the next thread to release is the last one to
             * acquire. This is non-volatile since it is just used
             * as a heuristic, and would be great for threads to cache.
             *
             * <p>Can outlive the Thread for which it is caching the read
             * hold count, but avoids garbage retention by not retaining a
             * reference to the Thread.
             *
             * <p>Accessed via a benign data race; relies on the memory
             * model's final field and out-of-thin-air guarantees.
             */
            private transient HoldCounter cachedHoldCounter;
    
            /**
             * firstReader is the first thread to have acquired the read lock.
             * firstReaderHoldCount is firstReader's hold count.
             *
             * <p>More precisely, firstReader is the unique thread that last
             * changed the shared count from 0 to 1, and has not released the
             * read lock since then; null if there is no such thread.
             *
             * <p>Cannot cause garbage retention unless the thread terminated
             * without relinquishing its read locks, since tryReleaseShared
             * sets it to null.
             *
             * <p>Accessed via a benign data race; relies on the memory
             * model's out-of-thin-air guarantees for references.
             *
             * <p>This allows tracking of read holds for uncontended read
             * locks to be very cheap.
             */
            private transient Thread firstReader = null;
            private transient int firstReaderHoldCount;
    
            Sync() {
                readHolds = new ThreadLocalHoldCounter();
                setState(getState()); // ensures visibility of readHolds
            }
    
            /*
             * Acquires and releases use the same code for fair and
             * nonfair locks, but differ in whether/how they allow barging
             * when queues are non-empty.
             */
    
            /**
             * Returns true if the current thread, when trying to acquire
             * the read lock, and otherwise eligible to do so, should block
             * because of policy for overtaking other waiting threads.
             */
            abstract boolean readerShouldBlock();
    
            /**
             * Returns true if the current thread, when trying to acquire
             * the write lock, and otherwise eligible to do so, should block
             * because of policy for overtaking other waiting threads.
             */
            abstract boolean writerShouldBlock();
    
            /*
             * Note that tryRelease and tryAcquire can be called by
             * Conditions. So it is possible that their arguments contain
             * both read and write holds that are all released during a
             * condition wait and re-established in tryAcquire.
             */
    
            protected final boolean tryRelease(int releases) {
                if (!isHeldExclusively())
                    throw new IllegalMonitorStateException();
                int nextc = getState() - releases;
                boolean free = exclusiveCount(nextc) == 0;
                if (free)
                    setExclusiveOwnerThread(null);
                setState(nextc);
                return free;
            }
    
            protected final boolean tryAcquire(int acquires) {
                /*
                 * Walkthrough:
                 * 1. If read count nonzero or write count nonzero
                 *    and owner is a different thread, fail.
                 * 2. If count would saturate, fail. (This can only
                 *    happen if count is already nonzero.)
                 * 3. Otherwise, this thread is eligible for lock if
                 *    it is either a reentrant acquire or
                 *    queue policy allows it. If so, update state
                 *    and set owner.
                 */
                Thread current = Thread.currentThread();
                int c = getState();
                int w = exclusiveCount(c);
                if (c != 0) {
                    // (Note: if c != 0 and w == 0 then shared count != 0)
                    if (w == 0 || current != getExclusiveOwnerThread())
                        return false;
                    if (w + exclusiveCount(acquires) > MAX_COUNT)
                        throw new Error("Maximum lock count exceeded");
                    // Reentrant acquire
                    setState(c + acquires);
                    return true;
                }
                if (writerShouldBlock() ||
                        !compareAndSetState(c, c + acquires))
                    return false;
                setExclusiveOwnerThread(current);
                return true;
            }
    
            /**
             * 重写aqs当中业务逻辑
             * @param unused
             * @return
             */
            protected final boolean tryReleaseShared(int unused) {
                Thread current = Thread.currentThread();
                if (firstReader == current) {
                    // assert firstReaderHoldCount > 0;
                    if (firstReaderHoldCount == 1)
                        firstReader = null;
                    else
                        firstReaderHoldCount--;
                } else {
                    HoldCounter rh = cachedHoldCounter;
                    if (rh == null || rh.tid != getThreadId(current))
                        rh = readHolds.get();
                    int count = rh.count;
                    if (count <= 1) {
                        readHolds.remove();
                        if (count <= 0)
                            throw unmatchedUnlockException();
                    }
                    --rh.count;
                }
                for (;;) {
                    int c = getState();
                    int nextc = c - SHARED_UNIT;
                    if (compareAndSetState(c, nextc))
                        // Releasing the read lock has no effect on readers,
                        // but it may allow waiting writers to proceed if
                        // both read and write locks are now free.
                        return nextc == 0;
                }
            }
    
            private IllegalMonitorStateException unmatchedUnlockException() {
                return new IllegalMonitorStateException(
                        "attempt to unlock read lock, not locked by current thread");
            }
    
            /**
             * 尝试加共享锁
             */
            protected final int tryAcquireShared(int unused) {
                Thread current = Thread.currentThread();
                int c = getState();
                /**
                 * 如果state状态当前被加独占写锁,则返回加共享锁失败
                 */
                if (exclusiveCount(c) != 0 &&
                        getExclusiveOwnerThread() != current)
                    return -1;
                int r = sharedCount(c); //读锁数量
                if (!readerShouldBlock() && //读锁是否应该阻塞
                        r < MAX_COUNT &&
                        compareAndSetState(c, c + SHARED_UNIT)) {
                    if (r == 0) { //第一次加读锁
                        firstReader = current;
                        firstReaderHoldCount = 1;//第一个读锁Thread持有锁数量
                    } else if (firstReader == current) {
                        firstReaderHoldCount++; //当前Thread是加锁,读锁数量加1
                    } else {
                        HoldCounter rh = cachedHoldCounter;
                        if (rh == null || rh.tid != getThreadId(current))
                            //每一个加锁的thread对应一个HoldCounter
                            cachedHoldCounter = rh = readHolds.get();//从threadLocal中取出变量
                        else if (rh.count == 0)
                            readHolds.set(rh);
                        rh.count++;//
                    }
                    return 1;
                }
                return fullTryAcquireShared(current);
            }
    
            /**
             * Full version of acquire for reads, that handles CAS misses
             * and reentrant reads not dealt with in tryAcquireShared.
             */
            final int fullTryAcquireShared(Thread current) {
                /*
                 * This code is in part redundant with that in
                 * tryAcquireShared but is simpler overall by not
                 * complicating tryAcquireShared with interactions between
                 * retries and lazily reading hold counts.
                 */
                HoldCounter rh = null;
                for (;;) {
                    int c = getState();
                    if (exclusiveCount(c) != 0) {
                        if (getExclusiveOwnerThread() != current)
                            return -1;
                        // else we hold the exclusive lock; blocking here
                        // would cause deadlock.
                    } else if (readerShouldBlock()) {
                        // Make sure we're not acquiring read lock reentrantly
                        if (firstReader == current) {
                            // assert firstReaderHoldCount > 0;
                        } else {
                            if (rh == null) {
                                rh = cachedHoldCounter;
                                if (rh == null || rh.tid != getThreadId(current)) {
                                    rh = readHolds.get();
                                    if (rh.count == 0)
                                        readHolds.remove();
                                }
                            }
                            if (rh.count == 0)
                                return -1;
                        }
                    }
                    if (sharedCount(c) == MAX_COUNT)
                        throw new Error("Maximum lock count exceeded");
                    if (compareAndSetState(c, c + SHARED_UNIT)) {
                        if (sharedCount(c) == 0) {
                            firstReader = current;
                            firstReaderHoldCount = 1;
                        } else if (firstReader == current) {
                            firstReaderHoldCount++;
                        } else {
                            if (rh == null)
                                rh = cachedHoldCounter;
                            if (rh == null || rh.tid != getThreadId(current))
                                rh = readHolds.get();
                            else if (rh.count == 0)
                                readHolds.set(rh);
                            rh.count++;
                            cachedHoldCounter = rh; // cache for release
                        }
                        return 1;
                    }
                }
            }
    
            /**
             * Performs tryLock for write, enabling barging in both modes.
             * This is identical in effect to tryAcquire except for lack
             * of calls to writerShouldBlock.
             */
            final boolean tryWriteLock() {
                Thread current = Thread.currentThread();
                int c = getState();
                if (c != 0) {
                    int w = exclusiveCount(c);
                    if (w == 0 || current != getExclusiveOwnerThread())
                        return false;
                    if (w == MAX_COUNT)
                        throw new Error("Maximum lock count exceeded");
                }
                if (!compareAndSetState(c, c + 1))
                    return false;
                setExclusiveOwnerThread(current);
                return true;
            }
    
            /**
             * Performs tryLock for read, enabling barging in both modes.
             * This is identical in effect to tryAcquireShared except for
             * lack of calls to readerShouldBlock.
             */
            final boolean tryReadLock() {
                Thread current = Thread.currentThread();
                for (;;) {
                    int c = getState();
                    if (exclusiveCount(c) != 0 &&
                            getExclusiveOwnerThread() != current)
                        return false;
                    int r = sharedCount(c);
                    if (r == MAX_COUNT)
                        throw new Error("Maximum lock count exceeded");
                    if (compareAndSetState(c, c + SHARED_UNIT)) {
                        if (r == 0) {
                            firstReader = current;
                            firstReaderHoldCount = 1;
                        } else if (firstReader == current) {
                            firstReaderHoldCount++;
                        } else {
                            HoldCounter rh = cachedHoldCounter;
                            if (rh == null || rh.tid != getThreadId(current))
                                cachedHoldCounter = rh = readHolds.get();
                            else if (rh.count == 0)
                                readHolds.set(rh);
                            rh.count++;
                        }
                        return true;
                    }
                }
            }
    
            protected final boolean isHeldExclusively() {
                // While we must in general read state before owner,
                // we don't need to do so to check if current thread is owner
                return getExclusiveOwnerThread() == Thread.currentThread();
            }
    
            // Methods relayed to outer class
    
            final ConditionObject newCondition() {
                return new ConditionObject();
            }
    
            final Thread getOwner() {
                // Must read state before owner to ensure memory consistency
                return ((exclusiveCount(getState()) == 0) ?
                        null :
                        getExclusiveOwnerThread());
            }
    
            final int getReadLockCount() {
                return sharedCount(getState());
            }
    
            final boolean isWriteLocked() {
                return exclusiveCount(getState()) != 0;
            }
    
            final int getWriteHoldCount() {
                return isHeldExclusively() ? exclusiveCount(getState()) : 0;
            }
    
            final int getReadHoldCount() {
                if (getReadLockCount() == 0)
                    return 0;
    
                Thread current = Thread.currentThread();
                if (firstReader == current)
                    return firstReaderHoldCount;
    
                HoldCounter rh = cachedHoldCounter;
                if (rh != null && rh.tid == getThreadId(current))
                    return rh.count;
    
                int count = readHolds.get().count;
                if (count == 0) readHolds.remove();
                return count;
            }
    
            /**
             * Reconstitutes the instance from a stream (that is, deserializes it).
             */
            private void readObject(java.io.ObjectInputStream s)
                    throws java.io.IOException, ClassNotFoundException {
                s.defaultReadObject();
                readHolds = new ThreadLocalHoldCounter();
                setState(0); // reset to unlocked state
            }
    
            final int getCount() { return getState(); }
        }
    
        /**
         * Nonfair version of Sync
         */
        static final class NonfairSync extends Sync {
            private static final long serialVersionUID = -8159625535654395037L;
            final boolean writerShouldBlock() {
                return false; // writers can always barge
            }
            final boolean readerShouldBlock() {
                /* As a heuristic to avoid indefinite writer starvation,
                 * block if the thread that momentarily appears to be head
                 * of queue, if one exists, is a waiting writer.  This is
                 * only a probabilistic effect since a new reader will not
                 * block if there is a waiting writer behind other enabled
                 * readers that have not yet drained from the queue.
                 */
                return apparentlyFirstQueuedIsExclusive();
            }
        }
    
        /**
         * Fair version of Sync
         */
        static final class FairSync extends Sync {
            private static final long serialVersionUID = -2274990926593161451L;
            final boolean writerShouldBlock() {
                return hasQueuedPredecessors();
            }
            final boolean readerShouldBlock() {
                return hasQueuedPredecessors();
            }
        }
    
        /**
         * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
         */
        public static class ReadLock implements Lock, java.io.Serializable {
            private static final long serialVersionUID = -5992448646407690164L;
            private final Sync sync;
    
            /**
             * Constructor for use by subclasses
             *
             * @param lock the outer lock object
             * @throws NullPointerException if the lock is null
             */
            protected ReadLock(ReentrantReadWriteLock lock) {
                sync = lock.sync;
            }
    
            /**
             * Acquires the read lock.
             *
             * <p>Acquires the read lock if the write lock is not held by
             * another thread and returns immediately.
             *
             * <p>If the write lock is held by another thread then
             * the current thread becomes disabled for thread scheduling
             * purposes and lies dormant until the read lock has been acquired.
             */
            public void lock() {
                sync.acquireShared(1);
            }
    
            /**
             * Acquires the read lock unless the current thread is
             * {@linkplain Thread#interrupt interrupted}.
             *
             * <p>Acquires the read lock if the write lock is not held
             * by another thread and returns immediately.
             *
             * <p>If the write lock is held by another thread then the
             * current thread becomes disabled for thread scheduling
             * purposes and lies dormant until one of two things happens:
             *
             * <ul>
             *
             * <li>The read lock is acquired by the current thread; or
             *
             * <li>Some other thread {@linkplain Thread#interrupt interrupts}
             * the current thread.
             *
             * </ul>
             *
             * <p>If the current thread:
             *
             * <ul>
             *
             * <li>has its interrupted status set on entry to this method; or
             *
             * <li>is {@linkplain Thread#interrupt interrupted} while
             * acquiring the read lock,
             *
             * </ul>
             *
             * then {@link InterruptedException} is thrown and the current
             * thread's interrupted status is cleared.
             *
             * <p>In this implementation, as this method is an explicit
             * interruption point, preference is given to responding to
             * the interrupt over normal or reentrant acquisition of the
             * lock.
             *
             * @throws InterruptedException if the current thread is interrupted
             */
            public void lockInterruptibly() throws InterruptedException {
                sync.acquireSharedInterruptibly(1);
            }
    
            /**
             * Acquires the read lock only if the write lock is not held by
             * another thread at the time of invocation.
             *
             * <p>Acquires the read lock if the write lock is not held by
             * another thread and returns immediately with the value
             * {@code true}. Even when this lock has been set to use a
             * fair ordering policy, a call to {@code tryLock()}
             * <em>will</em> immediately acquire the read lock if it is
             * available, whether or not other threads are currently
             * waiting for the read lock.  This &quot;barging&quot; behavior
             * can be useful in certain circumstances, even though it
             * breaks fairness. If you want to honor the fairness setting
             * for this lock, then use {@link #tryLock(long, TimeUnit)
             * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
             * (it also detects interruption).
             *
             * <p>If the write lock is held by another thread then
             * this method will return immediately with the value
             * {@code false}.
             *
             * @return {@code true} if the read lock was acquired
             */
            public boolean tryLock() {
                return sync.tryReadLock();
            }
    
            /**
             * Acquires the read lock if the write lock is not held by
             * another thread within the given waiting time and the
             * current thread has not been {@linkplain Thread#interrupt
             * interrupted}.
             *
             * <p>Acquires the read lock if the write lock is not held by
             * another thread and returns immediately with the value
             * {@code true}. If this lock has been set to use a fair
             * ordering policy then an available lock <em>will not</em> be
             * acquired if any other threads are waiting for the
             * lock. This is in contrast to the {@link #tryLock()}
             * method. If you want a timed {@code tryLock} that does
             * permit barging on a fair lock then combine the timed and
             * un-timed forms together:
             *
             *  <pre> {@code
             * if (lock.tryLock() ||
             *     lock.tryLock(timeout, unit)) {
             *   ...
             * }}</pre>
             *
             * <p>If the write lock is held by another thread then the
             * current thread becomes disabled for thread scheduling
             * purposes and lies dormant until one of three things happens:
             *
             * <ul>
             *
             * <li>The read lock is acquired by the current thread; or
             *
             * <li>Some other thread {@linkplain Thread#interrupt interrupts}
             * the current thread; or
             *
             * <li>The specified waiting time elapses.
             *
             * </ul>
             *
             * <p>If the read lock is acquired then the value {@code true} is
             * returned.
             *
             * <p>If the current thread:
             *
             * <ul>
             *
             * <li>has its interrupted status set on entry to this method; or
             *
             * <li>is {@linkplain Thread#interrupt interrupted} while
             * acquiring the read lock,
             *
             * </ul> then {@link InterruptedException} is thrown and the
             * current thread's interrupted status is cleared.
             *
             * <p>If the specified waiting time elapses then the value
             * {@code false} is returned.  If the time is less than or
             * equal to zero, the method will not wait at all.
             *
             * <p>In this implementation, as this method is an explicit
             * interruption point, preference is given to responding to
             * the interrupt over normal or reentrant acquisition of the
             * lock, and over reporting the elapse of the waiting time.
             *
             * @param timeout the time to wait for the read lock
             * @param unit the time unit of the timeout argument
             * @return {@code true} if the read lock was acquired
             * @throws InterruptedException if the current thread is interrupted
             * @throws NullPointerException if the time unit is null
             */
            public boolean tryLock(long timeout, TimeUnit unit)
                    throws InterruptedException {
                return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
            }
    
            /**
             * Attempts to release this lock.
             *
             * <p>If the number of readers is now zero then the lock
             * is made available for write lock attempts.
             */
            public void unlock() {
                sync.releaseShared(1);
            }
    
            /**
             * Throws {@code UnsupportedOperationException} because
             * {@code ReadLocks} do not support conditions.
             *
             * @throws UnsupportedOperationException always
             */
            public Condition newCondition() {
                throw new UnsupportedOperationException();
            }
    
            /**
             * Returns a string identifying this lock, as well as its lock state.
             * The state, in brackets, includes the String {@code "Read locks ="}
             * followed by the number of held read locks.
             *
             * @return a string identifying this lock, as well as its lock state
             */
            public String toString() {
                int r = sync.getReadLockCount();
                return super.toString() +
                        "[Read locks = " + r + "]";
            }
        }
    
        /**
         * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
         */
        public static class WriteLock implements Lock, java.io.Serializable {
            private static final long serialVersionUID = -4992448646407690164L;
            private final Sync sync;
    
            /**
             * Constructor for use by subclasses
             *
             * @param lock the outer lock object
             * @throws NullPointerException if the lock is null
             */
            protected WriteLock(ReentrantReadWriteLock lock) {
                sync = lock.sync;
            }
    
            /**
             * Acquires the write lock.
             *
             * <p>Acquires the write lock if neither the read nor write lock
             * are held by another thread
             * and returns immediately, setting the write lock hold count to
             * one.
             *
             * <p>If the current thread already holds the write lock then the
             * hold count is incremented by one and the method returns
             * immediately.
             *
             * <p>If the lock is held by another thread then the current
             * thread becomes disabled for thread scheduling purposes and
             * lies dormant until the write lock has been acquired, at which
             * time the write lock hold count is set to one.
             */
            public void lock() {
                sync.acquire(1);
            }
    
            /**
             * Acquires the write lock unless the current thread is
             * {@linkplain Thread#interrupt interrupted}.
             *
             * <p>Acquires the write lock if neither the read nor write lock
             * are held by another thread
             * and returns immediately, setting the write lock hold count to
             * one.
             *
             * <p>If the current thread already holds this lock then the
             * hold count is incremented by one and the method returns
             * immediately.
             *
             * <p>If the lock is held by another thread then the current
             * thread becomes disabled for thread scheduling purposes and
             * lies dormant until one of two things happens:
             *
             * <ul>
             *
             * <li>The write lock is acquired by the current thread; or
             *
             * <li>Some other thread {@linkplain Thread#interrupt interrupts}
             * the current thread.
             *
             * </ul>
             *
             * <p>If the write lock is acquired by the current thread then the
             * lock hold count is set to one.
             *
             * <p>If the current thread:
             *
             * <ul>
             *
             * <li>has its interrupted status set on entry to this method;
             * or
             *
             * <li>is {@linkplain Thread#interrupt interrupted} while
             * acquiring the write lock,
             *
             * </ul>
             *
             * then {@link InterruptedException} is thrown and the current
             * thread's interrupted status is cleared.
             *
             * <p>In this implementation, as this method is an explicit
             * interruption point, preference is given to responding to
             * the interrupt over normal or reentrant acquisition of the
             * lock.
             *
             * @throws InterruptedException if the current thread is interrupted
             */
            public void lockInterruptibly() throws InterruptedException {
                sync.acquireInterruptibly(1);
            }
    
            /**
             * Acquires the write lock only if it is not held by another thread
             * at the time of invocation.
             *
             * <p>Acquires the write lock if neither the read nor write lock
             * are held by another thread
             * and returns immediately with the value {@code true},
             * setting the write lock hold count to one. Even when this lock has
             * been set to use a fair ordering policy, a call to
             * {@code tryLock()} <em>will</em> immediately acquire the
             * lock if it is available, whether or not other threads are
             * currently waiting for the write lock.  This &quot;barging&quot;
             * behavior can be useful in certain circumstances, even
             * though it breaks fairness. If you want to honor the
             * fairness setting for this lock, then use {@link
             * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
             * which is almost equivalent (it also detects interruption).
             *
             * <p>If the current thread already holds this lock then the
             * hold count is incremented by one and the method returns
             * {@code true}.
             *
             * <p>If the lock is held by another thread then this method
             * will return immediately with the value {@code false}.
             *
             * @return {@code true} if the lock was free and was acquired
             * by the current thread, or the write lock was already held
             * by the current thread; and {@code false} otherwise.
             */
            public boolean tryLock( ) {
                return sync.tryWriteLock();
            }
    
            /**
             * Acquires the write lock if it is not held by another thread
             * within the given waiting time and the current thread has
             * not been {@linkplain Thread#interrupt interrupted}.
             *
             * <p>Acquires the write lock if neither the read nor write lock
             * are held by another thread
             * and returns immediately with the value {@code true},
             * setting the write lock hold count to one. If this lock has been
             * set to use a fair ordering policy then an available lock
             * <em>will not</em> be acquired if any other threads are
             * waiting for the write lock. This is in contrast to the {@link
             * #tryLock()} method. If you want a timed {@code tryLock}
             * that does permit barging on a fair lock then combine the
             * timed and un-timed forms together:
             *
             *  <pre> {@code
             * if (lock.tryLock() ||
             *     lock.tryLock(timeout, unit)) {
             *   ...
             * }}</pre>
             *
             * <p>If the current thread already holds this lock then the
             * hold count is incremented by one and the method returns
             * {@code true}.
             *
             * <p>If the lock is held by another thread then the current
             * thread becomes disabled for thread scheduling purposes and
             * lies dormant until one of three things happens:
             *
             * <ul>
             *
             * <li>The write lock is acquired by the current thread; or
             *
             * <li>Some other thread {@linkplain Thread#interrupt interrupts}
             * the current thread; or
             *
             * <li>The specified waiting time elapses
             *
             * </ul>
             *
             * <p>If the write lock is acquired then the value {@code true} is
             * returned and the write lock hold count is set to one.
             *
             * <p>If the current thread:
             *
             * <ul>
             *
             * <li>has its interrupted status set on entry to this method;
             * or
             *
             * <li>is {@linkplain Thread#interrupt interrupted} while
             * acquiring the write lock,
             *
             * </ul>
             *
             * then {@link InterruptedException} is thrown and the current
             * thread's interrupted status is cleared.
             *
             * <p>If the specified waiting time elapses then the value
             * {@code false} is returned.  If the time is less than or
             * equal to zero, the method will not wait at all.
             *
             * <p>In this implementation, as this method is an explicit
             * interruption point, preference is given to responding to
             * the interrupt over normal or reentrant acquisition of the
             * lock, and over reporting the elapse of the waiting time.
             *
             * @param timeout the time to wait for the write lock
             * @param unit the time unit of the timeout argument
             *
             * @return {@code true} if the lock was free and was acquired
             * by the current thread, or the write lock was already held by the
             * current thread; and {@code false} if the waiting time
             * elapsed before the lock could be acquired.
             *
             * @throws InterruptedException if the current thread is interrupted
             * @throws NullPointerException if the time unit is null
             */
            public boolean tryLock(long timeout, TimeUnit unit)
                    throws InterruptedException {
                return sync.tryAcquireNanos(1, unit.toNanos(timeout));
            }
    
            /**
             * Attempts to release this lock.
             *
             * <p>If the current thread is the holder of this lock then
             * the hold count is decremented. If the hold count is now
             * zero then the lock is released.  If the current thread is
             * not the holder of this lock then {@link
             * IllegalMonitorStateException} is thrown.
             *
             * @throws IllegalMonitorStateException if the current thread does not
             * hold this lock
             */
            public void unlock() {
                sync.release(1);
            }
    
            /**
             * Returns a {@link Condition} instance for use with this
             * {@link Lock} instance.
             * <p>The returned {@link Condition} instance supports the same
             * usages as do the {@link Object} monitor methods ({@link
             * Object#wait() wait}, {@link Object#notify notify}, and {@link
             * Object#notifyAll notifyAll}) when used with the built-in
             * monitor lock.
             *
             * <ul>
             *
             * <li>If this write lock is not held when any {@link
             * Condition} method is called then an {@link
             * IllegalMonitorStateException} is thrown.  (Read locks are
             * held independently of write locks, so are not checked or
             * affected. However it is essentially always an error to
             * invoke a condition waiting method when the current thread
             * has also acquired read locks, since other threads that
             * could unblock it will not be able to acquire the write
             * lock.)
             *
             * <li>When the condition {@linkplain Condition#await() waiting}
             * methods are called the write lock is released and, before
             * they return, the write lock is reacquired and the lock hold
             * count restored to what it was when the method was called.
             *
             * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
             * waiting then the wait will terminate, an {@link
             * InterruptedException} will be thrown, and the thread's
             * interrupted status will be cleared.
             *
             * <li> Waiting threads are signalled in FIFO order.
             *
             * <li>The ordering of lock reacquisition for threads returning
             * from waiting methods is the same as for threads initially
             * acquiring the lock, which is in the default case not specified,
             * but for <em>fair</em> locks favors those threads that have been
             * waiting the longest.
             *
             * </ul>
             *
             * @return the Condition object
             */
            public Condition newCondition() {
                return sync.newCondition();
            }
    
            /**
             * Returns a string identifying this lock, as well as its lock
             * state.  The state, in brackets includes either the String
             * {@code "Unlocked"} or the String {@code "Locked by"}
             * followed by the {@linkplain Thread#getName name} of the owning thread.
             *
             * @return a string identifying this lock, as well as its lock state
             */
            public String toString() {
                Thread o = sync.getOwner();
                return super.toString() + ((o == null) ?
                        "[Unlocked]" :
                        "[Locked by thread " + o.getName() + "]");
            }
    
            /**
             * Queries if this write lock is held by the current thread.
             * Identical in effect to {@link
             * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
             *
             * @return {@code true} if the current thread holds this lock and
             *         {@code false} otherwise
             * @since 1.6
             */
            public boolean isHeldByCurrentThread() {
                return sync.isHeldExclusively();
            }
    
            /**
             * Queries the number of holds on this write lock by the current
             * thread.  A thread has a hold on a lock for each lock action
             * that is not matched by an unlock action.  Identical in effect
             * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
             *
             * @return the number of holds on this lock by the current thread,
             *         or zero if this lock is not held by the current thread
             * @since 1.6
             */
            public int getHoldCount() {
                return sync.getWriteHoldCount();
            }
        }
    
        // Instrumentation and status
    
        /**
         * Returns {@code true} if this lock has fairness set true.
         *
         * @return {@code true} if this lock has fairness set true
         */
        public final boolean isFair() {
            return sync instanceof FairSync;
        }
    
        /**
         * Returns the thread that currently owns the write lock, or
         * {@code null} if not owned. When this method is called by a
         * thread that is not the owner, the return value reflects a
         * best-effort approximation of current lock status. For example,
         * the owner may be momentarily {@code null} even if there are
         * threads trying to acquire the lock but have not yet done so.
         * This method is designed to facilitate construction of
         * subclasses that provide more extensive lock monitoring
         * facilities.
         *
         * @return the owner, or {@code null} if not owned
         */
        protected Thread getOwner() {
            return sync.getOwner();
        }
    
        /**
         * Queries the number of read locks held for this lock. This
         * method is designed for use in monitoring system state, not for
         * synchronization control.
         * @return the number of read locks held
         */
        public int getReadLockCount() {
            return sync.getReadLockCount();
        }
    
        /**
         * Queries if the write lock is held by any thread. This method is
         * designed for use in monitoring system state, not for
         * synchronization control.
         *
         * @return {@code true} if any thread holds the write lock and
         *         {@code false} otherwise
         */
        public boolean isWriteLocked() {
            return sync.isWriteLocked();
        }
    
        /**
         * Queries if the write lock is held by the current thread.
         *
         * @return {@code true} if the current thread holds the write lock and
         *         {@code false} otherwise
         */
        public boolean isWriteLockedByCurrentThread() {
            return sync.isHeldExclusively();
        }
    
        /**
         * 获取当前线程可重入写锁的持有数量
         */
        public int getWriteHoldCount() {
            return sync.getWriteHoldCount();
        }
    
        /**
         * 获取当前线程可重入读锁的持有数量
         */
        public int getReadHoldCount() {
            return sync.getReadHoldCount();
        }
    
        /**
         * 获取所有在同步队列中等待获取写锁的thread数量
         */
        protected Collection<Thread> getQueuedWriterThreads() {
            return sync.getExclusiveQueuedThreads();
        }
    
        /**
         * 获取所有在同步队列中等待获取读锁的thread数量
         */
        protected Collection<Thread> getQueuedReaderThreads() {
            return sync.getSharedQueuedThreads();
        }
    
        /**
         * 是否有在队列当中等待获取锁的线程
         */
        public final boolean hasQueuedThreads() {
            return sync.hasQueuedThreads();
        }
    
        /**
         * Queries whether the given thread is waiting to acquire either
         * the read or write lock. Note that because cancellations may
         * occur at any time, a {@code true} return does not guarantee
         * that this thread will ever acquire a lock.  This method is
         * designed primarily for use in monitoring of the system state.
         *
         * @param thread the thread
         * @return {@code true} if the given thread is queued waiting for this lock
         * @throws NullPointerException if the thread is null
         */
        public final boolean hasQueuedThread(Thread thread) {
            return sync.isQueued(thread);
        }
    
        /**
         * Returns an estimate of the number of threads waiting to acquire
         * either the read or write lock.  The value is only an estimate
         * because the number of threads may change dynamically while this
         * method traverses internal data structures.  This method is
         * designed for use in monitoring of the system state, not for
         * synchronization control.
         *
         * @return the estimated number of threads waiting for this lock
         */
        public final int getQueueLength() {
            return sync.getQueueLength();
        }
    
        /**
         * Returns a collection containing threads that may be waiting to
         * acquire either the read or write lock.  Because the actual set
         * of threads may change dynamically while constructing this
         * result, the returned collection is only a best-effort estimate.
         * The elements of the returned collection are in no particular
         * order.  This method is designed to facilitate construction of
         * subclasses that provide more extensive monitoring facilities.
         *
         * @return the collection of threads
         */
        protected Collection<Thread> getQueuedThreads() {
            return sync.getQueuedThreads();
        }
    
        /**
         * Queries whether any threads are waiting on the given condition
         * associated with the write lock. Note that because timeouts and
         * interrupts may occur at any time, a {@code true} return does
         * not guarantee that a future {@code signal} will awaken any
         * threads.  This method is designed primarily for use in
         * monitoring of the system state.
         *
         * @param condition the condition
         * @return {@code true} if there are any waiting threads
         * @throws IllegalMonitorStateException if this lock is not held
         * @throws IllegalArgumentException if the given condition is
         *         not associated with this lock
         * @throws NullPointerException if the condition is null
         */
        public boolean hasWaiters(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
        }
    
        /**
         * Returns an estimate of the number of threads waiting on the
         * given condition associated with the write lock. Note that because
         * timeouts and interrupts may occur at any time, the estimate
         * serves only as an upper bound on the actual number of waiters.
         * This method is designed for use in monitoring of the system
         * state, not for synchronization control.
         *
         * @param condition the condition
         * @return the estimated number of waiting threads
         * @throws IllegalMonitorStateException if this lock is not held
         * @throws IllegalArgumentException if the given condition is
         *         not associated with this lock
         * @throws NullPointerException if the condition is null
         */
        public int getWaitQueueLength(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
        }
    
        /**
         * Returns a collection containing those threads that may be
         * waiting on the given condition associated with the write lock.
         * Because the actual set of threads may change dynamically while
         * constructing this result, the returned collection is only a
         * best-effort estimate. The elements of the returned collection
         * are in no particular order.  This method is designed to
         * facilitate construction of subclasses that provide more
         * extensive condition monitoring facilities.
         *
         * @param condition the condition
         * @return the collection of threads
         * @throws IllegalMonitorStateException if this lock is not held
         * @throws IllegalArgumentException if the given condition is
         *         not associated with this lock
         * @throws NullPointerException if the condition is null
         */
        protected Collection<Thread> getWaitingThreads(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
        }
    
        /**
         * Returns a string identifying this lock, as well as its lock state.
         * The state, in brackets, includes the String {@code "Write locks ="}
         * followed by the number of reentrantly held write locks, and the
         * String {@code "Read locks ="} followed by the number of held
         * read locks.
         *
         * @return a string identifying this lock, as well as its lock state
         */
        public String toString() {
            int c = sync.getCount();
            int w = Sync.exclusiveCount(c);
            int r = Sync.sharedCount(c);
    
            return super.toString() +
                    "[Write locks = " + w + ", Read locks = " + r + "]";
        }
    
        /**
         * Returns the thread id for the given thread.  We must access
         * this directly rather than via method Thread.getId() because
         * getId() is not final, and has been known to be overridden in
         * ways that do not preserve unique mappings.
         */
        static final long getThreadId(Thread thread) {
            return UNSAFE.getLongVolatile(thread, TID_OFFSET);
        }
    
        // Unsafe mechanics
        private static final sun.misc.Unsafe UNSAFE;
        private static final long TID_OFFSET;
        static {
            try {
                UNSAFE = sun.misc.Unsafe.getUnsafe();
                Class<?> tk = Thread.class;
                TID_OFFSET = UNSAFE.objectFieldOffset
                        (tk.getDeclaredField("tid"));
            } catch (Exception e) {
                throw new Error(e);
            }
        }
    
    }
    View Code
    AbstractQueuedSynchronizer.java
    import sun.misc.Unsafe;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.LockSupport;
    
    /**
     * description:AQS同步器框架源码
     */
    public abstract class AbstractQueuedSynchronizer
            extends AbstractOwnableSynchronizer
            implements java.io.Serializable {
        private static final long serialVersionUID = 7373984972572414691L;
    
        /**
         * Creates a new {@code AbstractQueuedSynchronizer} instance
         * with initial synchronization state of zero.
         */
        protected AbstractQueuedSynchronizer() { }
    
        /**
         * Wait queue node class.
         *
         * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
         * Hagersten) lock queue. CLH locks are normally used for
         * spinlocks.  We instead use them for blocking synchronizers, but
         * use the same basic tactic of holding some of the control
         * information about a thread in the predecessor of its node.  A
         * "status" field in each node keeps track of whether a thread
         * should block.  A node is signalled when its predecessor
         * releases.  Each node of the queue otherwise serves as a
         * specific-notification-style monitor holding a single waiting
         * thread. The status field does NOT control whether threads are
         * granted locks etc though.  A thread may try to acquire if it is
         * first in the queue. But being first does not guarantee success;
         * it only gives the right to contend.  So the currently released
         * contender thread may need to rewait.
         *
         * <p>To enqueue into a CLH lock, you atomically splice it in as new
         * tail. To dequeue, you just set the head field.
         * <pre>
         *      +------+  prev +-----+       +-----+
         * head |      | <---- |     | <---- |     |  tail
         *      +------+       +-----+       +-----+
         * </pre>
         *
         * <p>Insertion into a CLH queue requires only a single atomic
         * operation on "tail", so there is a simple atomic point of
         * demarcation from unqueued to queued. Similarly, dequeuing
         * involves only updating the "head". However, it takes a bit
         * more work for nodes to determine who their successors are,
         * in part to deal with possible cancellation due to timeouts
         * and interrupts.
         *
         * <p>The "prev" links (not used in original CLH locks), are mainly
         * needed to handle cancellation. If a node is cancelled, its
         * successor is (normally) relinked to a non-cancelled
         * predecessor. For explanation of similar mechanics in the case
         * of spin locks, see the papers by Scott and Scherer at
         * http://www.cs.rochester.edu/u/scott/synchronization/
         *
         * <p>We also use "next" links to implement blocking mechanics.
         * The thread id for each node is kept in its own node, so a
         * predecessor signals the next node to wake up by traversing
         * next link to determine which thread it is.  Determination of
         * successor must avoid races with newly queued nodes to set
         * the "next" fields of their predecessors.  This is solved
         * when necessary by checking backwards from the atomically
         * updated "tail" when a node's successor appears to be null.
         * (Or, said differently, the next-links are an optimization
         * so that we don't usually need a backward scan.)
         *
         * <p>Cancellation introduces some conservatism to the basic
         * algorithms.  Since we must poll for cancellation of other
         * nodes, we can miss noticing whether a cancelled node is
         * ahead or behind us. This is dealt with by always unparking
         * successors upon cancellation, allowing them to stabilize on
         * a new predecessor, unless we can identify an uncancelled
         * predecessor who will carry this responsibility.
         *
         * <p>CLH queues need a dummy header node to get started. But
         * we don't create them on construction, because it would be wasted
         * effort if there is never contention. Instead, the node
         * is constructed and head and tail pointers are set upon first
         * contention.
         *
         * <p>Threads waiting on Conditions use the same nodes, but
         * use an additional link. Conditions only need to link nodes
         * in simple (non-concurrent) linked queues because they are
         * only accessed when exclusively held.  Upon await, a node is
         * inserted into a condition queue.  Upon signal, the node is
         * transferred to the main queue.  A special value of status
         * field is used to mark which queue a node is on.
         *
         * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
         * Scherer and Michael Scott, along with members of JSR-166
         * expert group, for helpful ideas, discussions, and critiques
         * on the design of this class.
         */
        static final class Node {
            /**
             * 标记节点为共享模式
             * */
            static final Node SHARED = new Node();
            /**
             *  标记节点为独占模式
             */
            static final Node EXCLUSIVE = null;
    
            /**
             * 在同步队列中等待的线程等待超时或者被中断,需要从同步队列中取消等待
             * */
            static final int CANCELLED =  1;
            /**
             *  后继节点的线程处于等待状态,而当前的节点如果释放了同步状态或者被取消,
             *  将会通知后继节点,使后继节点的线程得以运行。
             */
            static final int SIGNAL    = -1;
            /**
             *  节点在等待队列中,节点的线程等待在Condition上,当其他线程对Condition调用了signal()方法后,
             *  该节点会从等待队列中转移到同步队列中,加入到同步状态的获取中
             */
            static final int CONDITION = -2;
            /**
             * 表示下一次共享式同步状态获取将会被无条件地传播下去
             */
            static final int PROPAGATE = -3;
    
            /**
             * 标记当前节点的信号量状态 (1,0,-1,-2,-3)5种状态
             * 使用CAS更改状态,volatile保证线程可见性,高并发场景下,
             * 即被一个线程修改后,状态会立马让其他线程可见。
             */
            volatile int waitStatus;
    
            /**
             * 前驱节点,当前节点加入到同步队列中被设置
             */
            volatile Node prev;
    
            /**
             * 后继节点
             */
            volatile Node next;
    
            /**
             * 节点同步状态的线程
             */
            volatile Thread thread;
    
            /**
             * 等待队列中的后继节点,如果当前节点是共享的,那么这个字段是一个SHARED常量,
             * 也就是说节点类型(独占和共享)和等待队列中的后继节点共用同一个字段。
             */
            Node nextWaiter;
    
            /**
             * Returns true if node is waiting in shared mode.
             */
            final boolean isShared() {
                return nextWaiter == SHARED;
            }
    
            /**
             * 返回前驱节点
             */
            final Node predecessor() throws NullPointerException {
                Node p = prev;
                if (p == null)
                    throw new NullPointerException();
                else
                    return p;
            }
    
            Node() {    // Used to establish initial head or SHARED marker
            }
    
            Node(Thread thread, Node mode) {     // Used by addWaiter
                this.nextWaiter = mode;
                this.thread = thread;
            }
    
            Node(Thread thread, int waitStatus) { // Used by Condition
                this.waitStatus = waitStatus;
                this.thread = thread;
            }
        }
    
        /**
         * 指向同步等待队列的头节点
         */
        private transient volatile Node head;
    
        /**
         * 指向同步等待队列的尾节点
         */
        private transient volatile Node tail;
    
        /**
         * 同步资源状态
         */
        private volatile int state;
    
        /**
         * Returns the current value of synchronization state.
         * This operation has memory semantics of a {@code volatile} read.
         * @return current state value
         */
        protected final int getState() {
            return state;
        }
    
        /**
         * Sets the value of synchronization state.
         * This operation has memory semantics of a {@code volatile} write.
         * @param newState the new state value
         */
        protected final void setState(int newState) {
            state = newState;
        }
    
        /**
         * Atomically sets synchronization state to the given updated
         * value if the current state value equals the expected value.
         * This operation has memory semantics of a {@code volatile} read
         * and write.
         *
         * @param expect the expected value
         * @param update the new value
         * @return {@code true} if successful. False return indicates that the actual
         *         value was not equal to the expected value.
         */
        protected final boolean compareAndSetState(int expect, int update) {
            // See below for intrinsics setup to support this
            return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
        }
    
        // Queuing utilities
    
        /**
         * The number of nanoseconds for which it is faster to spin
         * rather than to use timed park. A rough estimate suffices
         * to improve responsiveness with very short timeouts.
         */
        static final long spinForTimeoutThreshold = 1000L;
    
        /**
         * 节点加入CLH同步队列
         */
        private Node enq(final Node node) {
            for (;;) {
                Node t = tail;
                if (t == null) { // Must initialize
                    //队列为空需要初始化,创建空的头节点
                    if (compareAndSetHead(new Node()))
                        tail = head;
                } else {
                    node.prev = t;
                    //set尾部节点
                    if (compareAndSetTail(t, node)) {//当前节点置为尾部
                        t.next = node; //前驱节点的next指针指向当前节点
                        return t;
                    }
                }
            }
        }
    
        /**
         * Creates and enqueues node for current thread and given mode.
         *
         * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
         * @return the new node
         */
        private Node addWaiter(Node mode) {
            // 1. 将当前线程构建成Node类型
            Node node = new Node(Thread.currentThread(), mode);
            // Try the fast path of enq; backup to full enq on failure
            Node pred = tail;
            // 2. 1当前尾节点是否为null?
            if (pred != null) {
                // 2.2 将当前节点尾插入的方式
                node.prev = pred;
                // 2.3 CAS将节点插入同步队列的尾部
                if (compareAndSetTail(pred, node)) {
                    pred.next = node;
                    return node;
                }
            }
            enq(node);
            return node;
        }
    
        /**
         * Sets head of queue to be node, thus dequeuing. Called only by
         * acquire methods.  Also nulls out unused fields for sake of GC
         * and to suppress unnecessary signals and traversals.
         *
         * @param node the node
         */
        private void setHead(Node node) {
            head = node;
            node.thread = null;
            node.prev = null;
        }
    
        /**
         *
         */
        private void unparkSuccessor(Node node) {
            //获取wait状态
            int ws = node.waitStatus;
            if (ws < 0)
                compareAndSetWaitStatus(node, ws, 0);// 将等待状态waitStatus设置为初始值0
    
            /**
             * 若后继结点为空,或状态为CANCEL(已失效),则从后尾部往前遍历找到最前的一个处于正常阻塞状态的结点
             * 进行唤醒
             */
            Node s = node.next;
            if (s == null || s.waitStatus > 0) {
                s = null;
                for (Node t = tail; t != null && t != node; t = t.prev)
                    if (t.waitStatus <= 0)
                        s = t;
            }
            if (s != null)
                LockSupport.unpark(s.thread);//唤醒线程
        }
    
        /**
         * 把当前结点设置为SIGNAL或者PROPAGATE
         * 唤醒head.next(B节点),B节点唤醒后可以竞争锁,成功后head->B,然后又会唤醒B.next,一直重复直到共享节点都唤醒
         * head节点状态为SIGNAL,重置head.waitStatus->0,唤醒head节点线程,唤醒后线程去竞争共享锁
         * head节点状态为0,将head.waitStatus->Node.PROPAGATE传播状态,表示需要将状态向后继节点传播
         */
        private void doReleaseShared() {
            for (;;) {
                Node h = head;
                if (h != null && h != tail) {
                    int ws = h.waitStatus;
                    if (ws == Node.SIGNAL) {//head是SIGNAL状态
                        /* head状态是SIGNAL,重置head节点waitStatus为0,这里不直接设为Node.PROPAGATE,
                         * 是因为unparkSuccessor(h)中,如果ws < 0会设置为0,所以ws先设置为0,再设置为PROPAGATE
                         * 这里需要控制并发,因为入口有setHeadAndPropagate跟release两个,避免两次unpark
                         */
                        if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
                            continue; //设置失败,重新循环
                        /* head状态为SIGNAL,且成功设置为0之后,唤醒head.next节点线程
                         * 此时head、head.next的线程都唤醒了,head.next会去竞争锁,成功后head会指向获取锁的节点,
                         * 也就是head发生了变化。看最底下一行代码可知,head发生变化后会重新循环,继续唤醒head的下一个节点
                         */
                        unparkSuccessor(h);
                        /*
                         * 如果本身头节点的waitStatus是出于重置状态(waitStatus==0)的,将其设置为“传播”状态。
                         * 意味着需要将状态向后一个节点传播
                         */
                    }
                    else if (ws == 0 &&
                            !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                        continue;                // loop on failed CAS
                }
                if (h == head) //如果head变了,重新循环
                    break;
            }
        }
    
        /**
         * 把node节点设置成head节点,且Node.waitStatus->Node.PROPAGATE
         */
        private void setHeadAndPropagate(Node node, int propagate) {
            Node h = head; //h用来保存旧的head节点
            setHead(node);//head引用指向node节点
            /* 这里意思有两种情况是需要执行唤醒操作
             * 1.propagate > 0 表示调用方指明了后继节点需要被唤醒
             * 2.头节点后面的节点需要被唤醒(waitStatus<0),不论是老的头结点还是新的头结点
             */
            if (propagate > 0 || h == null || h.waitStatus < 0 ||
                    (h = head) == null || h.waitStatus < 0) {
                Node s = node.next;
                if (s == null || s.isShared())//node是最后一个节点或者 node的后继节点是共享节点
                    /* 如果head节点状态为SIGNAL,唤醒head节点线程,重置head.waitStatus->0
                     * head节点状态为0(第一次添加时是0),设置head.waitStatus->Node.PROPAGATE表示状态需要向后继节点传播
                     */
                    doReleaseShared();
            }
        }
    
        // Utilities for various versions of acquire
    
        /**
         * Cancels an ongoing attempt to acquire.
         *
         * @param node the node
         */
        private void cancelAcquire(Node node) {
            // Ignore if node doesn't exist
            if (node == null)
                return;
    
            node.thread = null;
    
            // Skip cancelled predecessors
            Node pred = node.prev;
            while (pred.waitStatus > 0)
                node.prev = pred = pred.prev;
    
            // predNext is the apparent node to unsplice. CASes below will
            // fail if not, in which case, we lost race vs another cancel
            // or signal, so no further action is necessary.
            Node predNext = pred.next;
    
            // Can use unconditional write instead of CAS here.
            // After this atomic step, other Nodes can skip past us.
            // Before, we are free of interference from other threads.
            node.waitStatus = Node.CANCELLED;
    
            // If we are the tail, remove ourselves.
            if (node == tail && compareAndSetTail(node, pred)) {
                compareAndSetNext(pred, predNext, null);
            } else {
                // If successor needs signal, try to set pred's next-link
                // so it will get one. Otherwise wake it up to propagate.
                int ws;
                if (pred != head &&
                        ((ws = pred.waitStatus) == Node.SIGNAL ||
                                (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
                        pred.thread != null) {
                    Node next = node.next;
                    if (next != null && next.waitStatus <= 0)
                        compareAndSetNext(pred, predNext, next);
                } else {
                    unparkSuccessor(node);
                }
    
                node.next = node; // help GC
            }
        }
    
        /**
         * Checks and updates status for a node that failed to acquire.
         * Returns true if thread should block. This is the main signal
         * control in all acquire loops.  Requires that pred == node.prev.
         *
         * @param pred node's predecessor holding status
         * @param node the node
         * @return {@code true} if thread should block
         */
        private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
            int ws = pred.waitStatus;
            if (ws == Node.SIGNAL)
                /*
                 * 若前驱结点的状态是SIGNAL,意味着当前结点可以被安全地park
                 */
                return true;
            if (ws > 0) {
                /*
                 * 前驱节点状态如果被取消状态,将被移除出队列
                 */
                do {
                    node.prev = pred = pred.prev;
                } while (pred.waitStatus > 0);
                pred.next = node;
            } else {
                /*
                 * 当前驱节点waitStatus为 0 or PROPAGATE状态时
                 * 将其设置为SIGNAL状态,然后当前结点才可以可以被安全地park
                 */
                compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
            }
            return false;
        }
    
        /**
         * Convenience method to interrupt current thread.
         */
        static void selfInterrupt() {
            Thread.currentThread().interrupt();
        }
    
        /**
         * 阻塞当前节点,返回当前Thread的中断状态
         * LockSupport.park 底层实现逻辑调用系统内核功能 pthread_mutex_lock 阻塞线程
         */
        private final boolean parkAndCheckInterrupt() {
            LockSupport.park(this);//阻塞
            return Thread.interrupted();
        }
    
        /*
         * Various flavors of acquire, varying in exclusive/shared and
         * control modes.  Each is mostly the same, but annoyingly
         * different.  Only a little bit of factoring is possible due to
         * interactions of exception mechanics (including ensuring that we
         * cancel if tryAcquire throws exception) and other control, at
         * least not without hurting performance too much.
         */
    
        /**
         * 已经在队列当中的Thread节点,准备阻塞等待获取锁
         */
        final boolean acquireQueued(final Node node, int arg) {
            boolean failed = true;
            try {
                boolean interrupted = false;
                for (;;) {//死循环
                    final Node p = node.predecessor();//找到当前结点的前驱结点
                    if (p == head && tryAcquire(arg)) {//如果前驱结点是头结点,才tryAcquire,其他结点是没有机会tryAcquire的。
                        setHead(node);//获取同步状态成功,将当前结点设置为头结点。
                        p.next = null; // help GC
                        failed = false;
                        return interrupted;
                    }
                    /**
                     * 如果前驱节点不是Head,通过shouldParkAfterFailedAcquire判断是否应该阻塞
                     * 前驱节点信号量为-1,当前线程可以安全被parkAndCheckInterrupt用来阻塞线程
                     */
                    if (shouldParkAfterFailedAcquire(p, node) &&
                            parkAndCheckInterrupt())
                        interrupted = true;
                }
            } finally {
                if (failed)
                    cancelAcquire(node);
            }
        }
    
        /**
         * 与acquireQueued逻辑相似,唯一区别节点还不在队列当中需要先进行入队操作
         */
        private void doAcquireInterruptibly(int arg)
                throws InterruptedException {
            final Node node = addWaiter(Node.EXCLUSIVE);//以独占模式放入队列尾部
            boolean failed = true;
            try {
                for (;;) {
                    final Node p = node.predecessor();
                    if (p == head && tryAcquire(arg)) {
                        setHead(node);
                        p.next = null; // help GC
                        failed = false;
                        return;
                    }
                    if (shouldParkAfterFailedAcquire(p, node) &&
                            parkAndCheckInterrupt())
                        throw new InterruptedException();
                }
            } finally {
                if (failed)
                    cancelAcquire(node);
            }
        }
    
        /**
         * 独占模式定时获取
         */
        private boolean doAcquireNanos(int arg, long nanosTimeout)
                throws InterruptedException {
            if (nanosTimeout <= 0L)
                return false;
            final long deadline = System.nanoTime() + nanosTimeout;
            final Node node = addWaiter(Node.EXCLUSIVE);//加入队列
            boolean failed = true;
            try {
                for (;;) {
                    final Node p = node.predecessor();
                    if (p == head && tryAcquire(arg)) {
                        setHead(node);
                        p.next = null; // help GC
                        failed = false;
                        return true;
                    }
                    nanosTimeout = deadline - System.nanoTime();
                    if (nanosTimeout <= 0L)
                        return false;//超时直接返回获取失败
                    if (shouldParkAfterFailedAcquire(p, node) &&
                            nanosTimeout > spinForTimeoutThreshold)
                        //阻塞指定时长,超时则线程自动被唤醒
                        LockSupport.parkNanos(this, nanosTimeout);
                    if (Thread.interrupted())//当前线程中断状态
                        throw new InterruptedException();
                }
            } finally {
                if (failed)
                    cancelAcquire(node);
            }
        }
    
        /**
         * 尝试获取共享锁
         */
        private void doAcquireShared(int arg) {
            final Node node = addWaiter(Node.SHARED);//入队
            boolean failed = true;
            try {
                boolean interrupted = false;
                for (;;) {
                    final Node p = node.predecessor();//前驱节点
                    if (p == head) {
                        int r = tryAcquireShared(arg); //非公平锁实现,再尝试获取锁
                        //state==0时tryAcquireShared会返回>=0(CountDownLatch中返回的是1)。
                        // state为0说明共享次数已经到了,可以获取锁了
                        if (r >= 0) {//r>0表示state==0,前继节点已经释放锁,锁的状态为可被获取
                            //这一步设置node为head节点设置node.waitStatus->Node.PROPAGATE,然后唤醒node.thread
                            setHeadAndPropagate(node, r);
                            p.next = null; // help GC
                            if (interrupted)
                                selfInterrupt();
                            failed = false;
                            return;
                        }
                    }
                    //前继节点非head节点,将前继节点状态设置为SIGNAL,通过park挂起node节点的线程
                    if (shouldParkAfterFailedAcquire(p, node) &&
                            parkAndCheckInterrupt())
                        interrupted = true;
                }
            } finally {
                if (failed)
                    cancelAcquire(node);
            }
        }
    
        /**
         * Acquires in shared interruptible mode.
         * @param arg the acquire argument
         */
        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);
            }
        }
    
        /**
         * Acquires in shared timed mode.
         *
         * @param arg the acquire argument
         * @param nanosTimeout max wait time
         * @return {@code true} if acquired
         */
        private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
                throws InterruptedException {
            if (nanosTimeout <= 0L)
                return false;
            final long deadline = System.nanoTime() + nanosTimeout;
            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 true;
                        }
                    }
                    nanosTimeout = deadline - System.nanoTime();
                    if (nanosTimeout <= 0L)
                        return false;
                    if (shouldParkAfterFailedAcquire(p, node) &&
                            nanosTimeout > spinForTimeoutThreshold)
                        LockSupport.parkNanos(this, nanosTimeout);
                    if (Thread.interrupted())
                        throw new InterruptedException();
                }
            } finally {
                if (failed)
                    cancelAcquire(node);
            }
        }
    
        // Main exported methods
    
        /**
         * Attempts to acquire in exclusive mode. This method should query
         * if the state of the object permits it to be acquired in the
         * exclusive mode, and if so to acquire it.
         *
         * <p>This method is always invoked by the thread performing
         * acquire.  If this method reports failure, the acquire method
         * may queue the thread, if it is not already queued, until it is
         * signalled by a release from some other thread. This can be used
         * to implement method {@link Lock#tryLock()}.
         *
         * <p>The default
         * implementation throws {@link UnsupportedOperationException}.
         *
         * @param arg the acquire argument. This value is always the one
         *        passed to an acquire method, or is the value saved on entry
         *        to a condition wait.  The value is otherwise uninterpreted
         *        and can represent anything you like.
         * @return {@code true} if successful. Upon success, this object has
         *         been acquired.
         * @throws IllegalMonitorStateException if acquiring would place this
         *         synchronizer in an illegal state. This exception must be
         *         thrown in a consistent fashion for synchronization to work
         *         correctly.
         * @throws UnsupportedOperationException if exclusive mode is not supported
         */
        protected boolean tryAcquire(int arg) {
            throw new UnsupportedOperationException();
        }
    
        /**
         * Attempts to set the state to reflect a release in exclusive
         * mode.
         *
         * <p>This method is always invoked by the thread performing release.
         *
         * <p>The default implementation throws
         * {@link UnsupportedOperationException}.
         *
         * @param arg the release argument. This value is always the one
         *        passed to a release method, or the current state value upon
         *        entry to a condition wait.  The value is otherwise
         *        uninterpreted and can represent anything you like.
         * @return {@code true} if this object is now in a fully released
         *         state, so that any waiting threads may attempt to acquire;
         *         and {@code false} otherwise.
         * @throws IllegalMonitorStateException if releasing would place this
         *         synchronizer in an illegal state. This exception must be
         *         thrown in a consistent fashion for synchronization to work
         *         correctly.
         * @throws UnsupportedOperationException if exclusive mode is not supported
         */
        protected boolean tryRelease(int arg) {
            throw new UnsupportedOperationException();
        }
    
        /**
         * 共享式:共享式地获取同步状态。对于独占式同步组件来讲,同一时刻只有一个线程能获取到同步状态,
         * 其他线程都得去排队等待,其待重写的尝试获取同步状态的方法tryAcquire返回值为boolean,这很容易理解;
         * 对于共享式同步组件来讲,同一时刻可以有多个线程同时获取到同步状态,这也是“共享”的意义所在。
         * 本方法待被之类覆盖实现具体逻辑
         *  1.当返回值大于0时,表示获取同步状态成功,同时还有剩余同步状态可供其他线程获取;
         *
         * 2.当返回值等于0时,表示获取同步状态成功,但没有可用同步状态了;
    
         * 3.当返回值小于0时,表示获取同步状态失败。
         */
        protected int tryAcquireShared(int arg) {
            throw new UnsupportedOperationException();
        }
    
        /**
         * Attempts to set the state to reflect a release in shared mode.
         *
         * <p>This method is always invoked by the thread performing release.
         *
         * <p>The default implementation throws
         * {@link UnsupportedOperationException}.
         *
         * @param arg the release argument. This value is always the one
         *        passed to a release method, or the current state value upon
         *        entry to a condition wait.  The value is otherwise
         *        uninterpreted and can represent anything you like.
         * @return {@code true} if this release of shared mode may permit a
         *         waiting acquire (shared or exclusive) to succeed; and
         *         {@code false} otherwise
         * @throws IllegalMonitorStateException if releasing would place this
         *         synchronizer in an illegal state. This exception must be
         *         thrown in a consistent fashion for synchronization to work
         *         correctly.
         * @throws UnsupportedOperationException if shared mode is not supported
         */
        protected boolean tryReleaseShared(int arg) {
            throw new UnsupportedOperationException();
        }
    
        /**
         * Returns {@code true} if synchronization is held exclusively with
         * respect to the current (calling) thread.  This method is invoked
         * upon each call to a non-waiting {@link ConditionObject} method.
         * (Waiting methods instead invoke {@link #release}.)
         *
         * <p>The default implementation throws {@link
         * UnsupportedOperationException}. This method is invoked
         * internally only within {@link ConditionObject} methods, so need
         * not be defined if conditions are not used.
         *
         * @return {@code true} if synchronization is held exclusively;
         *         {@code false} otherwise
         * @throws UnsupportedOperationException if conditions are not supported
         */
        protected boolean isHeldExclusively() {
            throw new UnsupportedOperationException();
        }
    
        /**
         * Acquires in exclusive mode, ignoring interrupts.  Implemented
         * by invoking at least once {@link #tryAcquire},
         * returning on success.  Otherwise the thread is queued, possibly
         * repeatedly blocking and unblocking, invoking {@link
         * #tryAcquire} until success.  This method can be used
         * to implement method {@link Lock#lock}.
         *
         * @param arg the acquire argument.  This value is conveyed to
         *        {@link #tryAcquire} but is otherwise uninterpreted and
         *        can represent anything you like.
         */
        public final void acquire(int arg) {
            if (!tryAcquire(arg) &&
                    acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
                selfInterrupt();
        }
    
        /**
         * Acquires in exclusive mode, aborting if interrupted.
         * Implemented by first checking interrupt status, then invoking
         * at least once {@link #tryAcquire}, returning on
         * success.  Otherwise the thread is queued, possibly repeatedly
         * blocking and unblocking, invoking {@link #tryAcquire}
         * until success or the thread is interrupted.  This method can be
         * used to implement method {@link Lock#lockInterruptibly}.
         *
         * @param arg the acquire argument.  This value is conveyed to
         *        {@link #tryAcquire} but is otherwise uninterpreted and
         *        can represent anything you like.
         * @throws InterruptedException if the current thread is interrupted
         */
        public final void acquireInterruptibly(int arg)
                throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            if (!tryAcquire(arg))
                doAcquireInterruptibly(arg);
        }
    
        /**
         * Attempts to acquire in exclusive mode, aborting if interrupted,
         * and failing if the given timeout elapses.  Implemented by first
         * checking interrupt status, then invoking at least once {@link
         * #tryAcquire}, returning on success.  Otherwise, the thread is
         * queued, possibly repeatedly blocking and unblocking, invoking
         * {@link #tryAcquire} until success or the thread is interrupted
         * or the timeout elapses.  This method can be used to implement
         * method {@link Lock#tryLock(long, TimeUnit)}.
         *
         * @param arg the acquire argument.  This value is conveyed to
         *        {@link #tryAcquire} but is otherwise uninterpreted and
         *        can represent anything you like.
         * @param nanosTimeout the maximum number of nanoseconds to wait
         * @return {@code true} if acquired; {@code false} if timed out
         * @throws InterruptedException if the current thread is interrupted
         */
        public final boolean tryAcquireNanos(int arg, long nanosTimeout)
                throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            return tryAcquire(arg) ||
                    doAcquireNanos(arg, nanosTimeout);
        }
    
        /**
         * 释放独占模式持有的锁
         */
        public final boolean release(int arg) {
            if (tryRelease(arg)) {//释放一次锁
                Node h = head;
                if (h != null && h.waitStatus != 0)
                    unparkSuccessor(h);//唤醒后继结点
                return true;
            }
            return false;
        }
    
        /**
         * 请求获取共享锁
         */
        public final void acquireShared(int arg) {
            if (tryAcquireShared(arg) < 0)//返回值小于0,获取同步状态失败,排队去;获取同步状态成功,直接返回去干自己的事儿。
                doAcquireShared(arg);
        }
    
        /**
         * Acquires in shared mode, aborting if interrupted.  Implemented
         * by first checking interrupt status, then invoking at least once
         * {@link #tryAcquireShared}, returning on success.  Otherwise the
         * thread is queued, possibly repeatedly blocking and unblocking,
         * invoking {@link #tryAcquireShared} until success or the thread
         * is interrupted.
         * @param arg the acquire argument.
         * This value is conveyed to {@link #tryAcquireShared} but is
         * otherwise uninterpreted and can represent anything
         * you like.
         * @throws InterruptedException if the current thread is interrupted
         */
        public final void acquireSharedInterruptibly(int arg)
                throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            if (tryAcquireShared(arg) < 0)
                doAcquireSharedInterruptibly(arg);
        }
    
        /**
         * Attempts to acquire in shared mode, aborting if interrupted, and
         * failing if the given timeout elapses.  Implemented by first
         * checking interrupt status, then invoking at least once {@link
         * #tryAcquireShared}, returning on success.  Otherwise, the
         * thread is queued, possibly repeatedly blocking and unblocking,
         * invoking {@link #tryAcquireShared} until success or the thread
         * is interrupted or the timeout elapses.
         *
         * @param arg the acquire argument.  This value is conveyed to
         *        {@link #tryAcquireShared} but is otherwise uninterpreted
         *        and can represent anything you like.
         * @param nanosTimeout the maximum number of nanoseconds to wait
         * @return {@code true} if acquired; {@code false} if timed out
         * @throws InterruptedException if the current thread is interrupted
         */
        public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
                throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            return tryAcquireShared(arg) >= 0 ||
                    doAcquireSharedNanos(arg, nanosTimeout);
        }
    
        /**
         * Releases in shared mode.  Implemented by unblocking one or more
         * threads if {@link #tryReleaseShared} returns true.
         *
         * @param arg the release argument.  This value is conveyed to
         *        {@link #tryReleaseShared} but is otherwise uninterpreted
         *        and can represent anything you like.
         * @return the value returned from {@link #tryReleaseShared}
         */
        public final boolean releaseShared(int arg) {
            if (tryReleaseShared(arg)) {
                doReleaseShared();
                return true;
            }
            return false;
        }
    
        // Queue inspection methods
    
        /**
         * Queries whether any threads are waiting to acquire. Note that
         * because cancellations due to interrupts and timeouts may occur
         * at any time, a {@code true} return does not guarantee that any
         * other thread will ever acquire.
         *
         * <p>In this implementation, this operation returns in
         * constant time.
         *
         * @return {@code true} if there may be other threads waiting to acquire
         */
        public final boolean hasQueuedThreads() {
            return head != tail;
        }
    
        /**
         * Queries whether any threads have ever contended to acquire this
         * synchronizer; that is if an acquire method has ever blocked.
         *
         * <p>In this implementation, this operation returns in
         * constant time.
         *
         * @return {@code true} if there has ever been contention
         */
        public final boolean hasContended() {
            return head != null;
        }
    
        /**
         * Returns the first (longest-waiting) thread in the queue, or
         * {@code null} if no threads are currently queued.
         *
         * <p>In this implementation, this operation normally returns in
         * constant time, but may iterate upon contention if other threads are
         * concurrently modifying the queue.
         *
         * @return the first (longest-waiting) thread in the queue, or
         *         {@code null} if no threads are currently queued
         */
        public final Thread getFirstQueuedThread() {
            // handle only fast path, else relay
            return (head == tail) ? null : fullGetFirstQueuedThread();
        }
    
        /**
         * Version of getFirstQueuedThread called when fastpath fails
         */
        private Thread fullGetFirstQueuedThread() {
            /*
             * The first node is normally head.next. Try to get its
             * thread field, ensuring consistent reads: If thread
             * field is nulled out or s.prev is no longer head, then
             * some other thread(s) concurrently performed setHead in
             * between some of our reads. We try this twice before
             * resorting to traversal.
             */
            Node h, s;
            Thread st;
            if (((h = head) != null && (s = h.next) != null &&
                    s.prev == head && (st = s.thread) != null) ||
                    ((h = head) != null && (s = h.next) != null &&
                            s.prev == head && (st = s.thread) != null))
                return st;
    
            /*
             * Head's next field might not have been set yet, or may have
             * been unset after setHead. So we must check to see if tail
             * is actually first node. If not, we continue on, safely
             * traversing from tail back to head to find first,
             * guaranteeing termination.
             */
    
            Node t = tail;
            Thread firstThread = null;
            while (t != null && t != head) {
                Thread tt = t.thread;
                if (tt != null)
                    firstThread = tt;
                t = t.prev;
            }
            return firstThread;
        }
    
        /**
         * 判断当前线程是否在队列当中
         */
        public final boolean isQueued(Thread thread) {
            if (thread == null)
                throw new NullPointerException();
            for (Node p = tail; p != null; p = p.prev)
                if (p.thread == thread)
                    return true;
            return false;
        }
    
        /**
         * Returns {@code true} if the apparent first queued thread, if one
         * exists, is waiting in exclusive mode.  If this method returns
         * {@code true}, and the current thread is attempting to acquire in
         * shared mode (that is, this method is invoked from {@link
         * #tryAcquireShared}) then it is guaranteed that the current thread
         * is not the first queued thread.  Used only as a heuristic in
         * ReentrantReadWriteLock.
         */
        final boolean apparentlyFirstQueuedIsExclusive() {
            Node h, s;
            return (h = head) != null &&
                    (s = h.next)  != null &&
                    !s.isShared()         &&
                    s.thread != null;
        }
    
        /**
         * 判断当前节点是否有前驱节点
         */
        public final boolean hasQueuedPredecessors() {
            Node t = tail; // Read fields in reverse initialization order
            Node h = head;
            Node s;
            return h != t &&
                    ((s = h.next) == null || s.thread != Thread.currentThread());
        }
    
    
        // Instrumentation and monitoring methods
    
        /**
         * 同步队列长度
         */
        public final int getQueueLength() {
            int n = 0;
            for (Node p = tail; p != null; p = p.prev) {
                if (p.thread != null)
                    ++n;
            }
            return n;
        }
    
        /**
         * 获取队列等待thread集合
         */
        public final Collection<Thread> getQueuedThreads() {
            ArrayList<Thread> list = new ArrayList<Thread>();
            for (Node p = tail; p != null; p = p.prev) {
                Thread t = p.thread;
                if (t != null)
                    list.add(t);
            }
            return list;
        }
    
        /**
         * 获取独占模式等待thread线程集合
         */
        public final Collection<Thread> getExclusiveQueuedThreads() {
            ArrayList<Thread> list = new ArrayList<Thread>();
            for (Node p = tail; p != null; p = p.prev) {
                if (!p.isShared()) {
                    Thread t = p.thread;
                    if (t != null)
                        list.add(t);
                }
            }
            return list;
        }
    
        /**
         * 获取共享模式等待thread集合
         */
        public final Collection<Thread> getSharedQueuedThreads() {
            ArrayList<Thread> list = new ArrayList<Thread>();
            for (Node p = tail; p != null; p = p.prev) {
                if (p.isShared()) {
                    Thread t = p.thread;
                    if (t != null)
                        list.add(t);
                }
            }
            return list;
        }
    
        /**
         * Returns a string identifying this synchronizer, as well as its state.
         * The state, in brackets, includes the String {@code "State ="}
         * followed by the current value of {@link #getState}, and either
         * {@code "nonempty"} or {@code "empty"} depending on whether the
         * queue is empty.
         *
         * @return a string identifying this synchronizer, as well as its state
         */
        public String toString() {
            int s = getState();
            String q  = hasQueuedThreads() ? "non" : "";
            return super.toString() +
                    "[State = " + s + ", " + q + "empty queue]";
        }
    
    
        // Internal support methods for Conditions
    
        /**
         * 判断节点是否在同步队列中
         */
        final boolean isOnSyncQueue(Node node) {
            //快速判断1:节点状态或者节点没有前置节点
            //注:同步队列是有头节点的,而条件队列没有
            if (node.waitStatus == Node.CONDITION || node.prev == null)
                return false;
            //快速判断2:next字段只有同步队列才会使用,条件队列中使用的是nextWaiter字段
            if (node.next != null) // If has successor, it must be on queue
                return true;
            //上面如果无法判断则进入复杂判断
            return findNodeFromTail(node);
        }
    
        /**
         * Returns true if node is on sync queue by searching backwards from tail.
         * Called only when needed by isOnSyncQueue.
         * @return true if present
         */
        private boolean findNodeFromTail(Node node) {
            Node t = tail;
            for (;;) {
                if (t == node)
                    return true;
                if (t == null)
                    return false;
                t = t.prev;
            }
        }
    
        /**
         * 将节点从条件队列当中移动到同步队列当中,等待获取锁
         */
        final boolean transferForSignal(Node node) {
            /*
             * 修改节点信号量状态为0,失败直接返回false
             */
            if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
                return false;
    
            /*
             * 加入同步队列尾部当中,返回前驱节点
             */
            Node p = enq(node);
            int ws = p.waitStatus;
            //前驱节点不可用 或者 修改信号量状态失败
            if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
                LockSupport.unpark(node.thread); //唤醒当前节点
            return true;
        }
    
        /**
         * Transfers node, if necessary, to sync queue after a cancelled wait.
         * Returns true if thread was cancelled before being signalled.
         *
         * @param node the node
         * @return true if cancelled before the node was signalled
         */
        final boolean transferAfterCancelledWait(Node node) {
            if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
                enq(node);
                return true;
            }
            /*
             * If we lost out to a signal(), then we can't proceed
             * until it finishes its enq().  Cancelling during an
             * incomplete transfer is both rare and transient, so just
             * spin.
             */
            while (!isOnSyncQueue(node))
                Thread.yield();
            return false;
        }
    
        /**
         * 入参就是新创建的节点,即当前节点
         */
        final int fullyRelease(Node node) {
            boolean failed = true;
            try {
                //这里这个取值要注意,获取当前的state并释放,这从另一个角度说明必须是独占锁
                //可以考虑下这个逻辑放在共享锁下面会发生什么?
                int savedState = getState();
                if (release(savedState)) {
                    failed = false;
                    return savedState;
                } else {
                    //如果这里释放失败,则抛出异常
                    throw new IllegalMonitorStateException();
                }
            } finally {
                /**
                 * 如果释放锁失败,则把节点取消,由这里就能看出来上面添加节点的逻辑中
                 * 只需要判断最后一个节点是否被取消就可以了
                 */
                if (failed)
                    node.waitStatus = Node.CANCELLED;
            }
        }
    
        // Instrumentation methods for conditions
    
        /**
         * Queries whether the given ConditionObject
         * uses this synchronizer as its lock.
         *
         * @param condition the condition
         * @return {@code true} if owned
         * @throws NullPointerException if the condition is null
         */
        public final boolean owns(ConditionObject condition) {
            return condition.isOwnedBy(this);
        }
    
        /**
         * Queries whether any threads are waiting on the given condition
         * associated with this synchronizer. Note that because timeouts
         * and interrupts may occur at any time, a {@code true} return
         * does not guarantee that a future {@code signal} will awaken
         * any threads.  This method is designed primarily for use in
         * monitoring of the system state.
         *
         * @param condition the condition
         * @return {@code true} if there are any waiting threads
         * @throws IllegalMonitorStateException if exclusive synchronization
         *         is not held
         * @throws IllegalArgumentException if the given condition is
         *         not associated with this synchronizer
         * @throws NullPointerException if the condition is null
         */
        public final boolean hasWaiters(ConditionObject condition) {
            if (!owns(condition))
                throw new IllegalArgumentException("Not owner");
            return condition.hasWaiters();
        }
    
        /**
         * 获取条件队列长度
         */
        public final int getWaitQueueLength(ConditionObject condition) {
            if (!owns(condition))
                throw new IllegalArgumentException("Not owner");
            return condition.getWaitQueueLength();
        }
    
        /**
         * 获取条件队列当中所有等待的thread集合
         */
        public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
            if (!owns(condition))
                throw new IllegalArgumentException("Not owner");
            return condition.getWaitingThreads();
        }
    
        /**
         * 条件对象,实现基于条件的具体行为
         */
        public class ConditionObject implements Condition, java.io.Serializable {
            private static final long serialVersionUID = 1173984872572414699L;
            /** First node of condition queue. */
            private transient Node firstWaiter;
            /** Last node of condition queue. */
            private transient Node lastWaiter;
    
            /**
             * Creates a new {@code ConditionObject} instance.
             */
            public ConditionObject() { }
    
            // Internal methods
    
            /**
             * 1.与同步队列不同,条件队列头尾指针是firstWaiter跟lastWaiter
             * 2.条件队列是在获取锁之后,也就是临界区进行操作,因此很多地方不用考虑并发
             */
            private Node addConditionWaiter() {
                Node t = lastWaiter;
                //如果最后一个节点被取消,则删除队列中被取消的节点
                //至于为啥是最后一个节点后面会分析
                if (t != null && t.waitStatus != Node.CONDITION) {
                    //删除所有被取消的节点
                    unlinkCancelledWaiters();
                    t = lastWaiter;
                }
                //创建一个类型为CONDITION的节点并加入队列,由于在临界区,所以这里不用并发控制
                Node node = new Node(Thread.currentThread(), Node.CONDITION);
                if (t == null)
                    firstWaiter = node;
                else
                    t.nextWaiter = node;
                lastWaiter = node;
                return node;
            }
    
            /**
             * 发信号,通知遍历条件队列当中的节点转移到同步队列当中,准备排队获取锁
             */
            private void doSignal(Node first) {
                do {
                    if ( (firstWaiter = first.nextWaiter) == null)
                        lastWaiter = null;
                    first.nextWaiter = null;
                } while (!transferForSignal(first) && //转移节点
                        (first = firstWaiter) != null);
            }
    
            /**
             * 通知所有节点移动到同步队列当中,并将节点从条件队列删除
             */
            private void doSignalAll(Node first) {
                lastWaiter = firstWaiter = null;
                do {
                    Node next = first.nextWaiter;
                    first.nextWaiter = null;
                    transferForSignal(first);
                    first = next;
                } while (first != null);
            }
    
            /**
             * 删除条件队列当中被取消的节点
             */
            private void unlinkCancelledWaiters() {
                Node t = firstWaiter;
                Node trail = null;
                while (t != null) {
                    Node next = t.nextWaiter;
                    if (t.waitStatus != Node.CONDITION) {
                        t.nextWaiter = null;
                        if (trail == null)
                            firstWaiter = next;
                        else
                            trail.nextWaiter = next;
                        if (next == null)
                            lastWaiter = trail;
                    }
                    else
                        trail = t;
                    t = next;
                }
            }
    
            // public methods
    
            /**
             * 发新号,通知条件队列当中节点到同步队列当中去排队
             *
             */
            public final void signal() {
                if (!isHeldExclusively())//节点不能已经持有独占锁
                    throw new IllegalMonitorStateException();
                Node first = firstWaiter;
                if (first != null)
                    /**
                     * 发信号通知条件队列的节点准备到同步队列当中去排队
                     */
                    doSignal(first);
            }
    
            /**
             * 唤醒所有条件队列的节点转移到同步队列当中
             */
            public final void signalAll() {
                if (!isHeldExclusively())
                    throw new IllegalMonitorStateException();
                Node first = firstWaiter;
                if (first != null)
                    doSignalAll(first);
            }
    
            /**
             * Implements uninterruptible condition wait.
             * <ol>
             * <li> Save lock state returned by {@link #getState}.
             * <li> Invoke {@link #release} with saved state as argument,
             *      throwing IllegalMonitorStateException if it fails.
             * <li> Block until signalled.
             * <li> Reacquire by invoking specialized version of
             *      {@link #acquire} with saved state as argument.
             * </ol>
             */
            public final void awaitUninterruptibly() {
                Node node = addConditionWaiter();
                int savedState = fullyRelease(node);
                boolean interrupted = false;
                while (!isOnSyncQueue(node)) {
                    LockSupport.park(this);
                    if (Thread.interrupted())
                        interrupted = true;
                }
                if (acquireQueued(node, savedState) || interrupted)
                    selfInterrupt();
            }
    
            /*
             * For interruptible waits, we need to track whether to throw
             * InterruptedException, if interrupted while blocked on
             * condition, versus reinterrupt current thread, if
             * interrupted while blocked waiting to re-acquire.
             */
    
            /** 该模式表示在退出等待时重新中断 */
            private static final int REINTERRUPT =  1;
            /** 异常中断 */
            private static final int THROW_IE    = -1;
    
            /**
             * 这里的判断逻辑是:
             * 1.如果现在不是中断的,即正常被signal唤醒则返回0
             * 2.如果节点由中断加入同步队列则返回THROW_IE,由signal加入同步队列则返回REINTERRUPT
             */
            private int checkInterruptWhileWaiting(Node node) {
                return Thread.interrupted() ?
                        (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
                        0;
            }
    
            /**
             * 根据中断时机选择抛出异常或者设置线程中断状态
             */
            private void reportInterruptAfterWait(int interruptMode)
                    throws InterruptedException {
                if (interruptMode == THROW_IE)
                    throw new InterruptedException();
                else if (interruptMode == REINTERRUPT)
                    selfInterrupt();
            }
    
            /**
             * 加入条件队列等待,条件队列入口
             */
            public final void await() throws InterruptedException {
                //如果当前线程被中断则直接抛出异常
                if (Thread.interrupted())
                    throw new InterruptedException();
                //把当前节点加入条件队列
                Node node = addConditionWaiter();
                //释放掉已经获取的独占锁资源
                int savedState = fullyRelease(node);
                int interruptMode = 0;
                //如果不在同步队列中则不断挂起
                while (!isOnSyncQueue(node)) {
                    LockSupport.park(this);
                    //这里被唤醒可能是正常的signal操作也可能是中断
                    if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                        break;
                }
                /**
                 * 走到这里说明节点已经条件满足被加入到了同步队列中或者中断了
                 * 这个方法很熟悉吧?就跟独占锁调用同样的获取锁方法,从这里可以看出条件队列只能用于独占锁
                 * 在处理中断之前首先要做的是从同步队列中成功获取锁资源
                 */
                if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                    interruptMode = REINTERRUPT;
                //走到这里说明已经成功获取到了独占锁,接下来就做些收尾工作
                //删除条件队列中被取消的节点
                if (node.nextWaiter != null) // clean up if cancelled
                    unlinkCancelledWaiters();
                //根据不同模式处理中断
                if (interruptMode != 0)
                    reportInterruptAfterWait(interruptMode);
            }
    
            /**
             * Implements timed condition wait.
             * <ol>
             * <li> If current thread is interrupted, throw InterruptedException.
             * <li> Save lock state returned by {@link #getState}.
             * <li> Invoke {@link #release} with saved state as argument,
             *      throwing IllegalMonitorStateException if it fails.
             * <li> Block until signalled, interrupted, or timed out.
             * <li> Reacquire by invoking specialized version of
             *      {@link #acquire} with saved state as argument.
             * <li> If interrupted while blocked in step 4, throw InterruptedException.
             * </ol>
             */
            public final long awaitNanos(long nanosTimeout)
                    throws InterruptedException {
                if (Thread.interrupted())
                    throw new InterruptedException();
                Node node = addConditionWaiter();
                int savedState = fullyRelease(node);
                final long deadline = System.nanoTime() + nanosTimeout;
                int interruptMode = 0;
                while (!isOnSyncQueue(node)) {
                    if (nanosTimeout <= 0L) {
                        transferAfterCancelledWait(node);
                        break;
                    }
                    if (nanosTimeout >= spinForTimeoutThreshold)
                        LockSupport.parkNanos(this, nanosTimeout);
                    if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                        break;
                    nanosTimeout = deadline - System.nanoTime();
                }
                if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                    interruptMode = REINTERRUPT;
                if (node.nextWaiter != null)
                    unlinkCancelledWaiters();
                if (interruptMode != 0)
                    reportInterruptAfterWait(interruptMode);
                return deadline - System.nanoTime();
            }
    
            /**
             * Implements absolute timed condition wait.
             * <ol>
             * <li> If current thread is interrupted, throw InterruptedException.
             * <li> Save lock state returned by {@link #getState}.
             * <li> Invoke {@link #release} with saved state as argument,
             *      throwing IllegalMonitorStateException if it fails.
             * <li> Block until signalled, interrupted, or timed out.
             * <li> Reacquire by invoking specialized version of
             *      {@link #acquire} with saved state as argument.
             * <li> If interrupted while blocked in step 4, throw InterruptedException.
             * <li> If timed out while blocked in step 4, return false, else true.
             * </ol>
             */
            public final boolean awaitUntil(Date deadline)
                    throws InterruptedException {
                long abstime = deadline.getTime();
                if (Thread.interrupted())
                    throw new InterruptedException();
                Node node = addConditionWaiter();
                int savedState = fullyRelease(node);
                boolean timedout = false;
                int interruptMode = 0;
                while (!isOnSyncQueue(node)) {
                    if (System.currentTimeMillis() > abstime) {
                        timedout = transferAfterCancelledWait(node);
                        break;
                    }
                    LockSupport.parkUntil(this, abstime);
                    if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                        break;
                }
                if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                    interruptMode = REINTERRUPT;
                if (node.nextWaiter != null)
                    unlinkCancelledWaiters();
                if (interruptMode != 0)
                    reportInterruptAfterWait(interruptMode);
                return !timedout;
            }
    
            /**
             * Implements timed condition wait.
             * <ol>
             * <li> If current thread is interrupted, throw InterruptedException.
             * <li> Save lock state returned by {@link #getState}.
             * <li> Invoke {@link #release} with saved state as argument,
             *      throwing IllegalMonitorStateException if it fails.
             * <li> Block until signalled, interrupted, or timed out.
             * <li> Reacquire by invoking specialized version of
             *      {@link #acquire} with saved state as argument.
             * <li> If interrupted while blocked in step 4, throw InterruptedException.
             * <li> If timed out while blocked in step 4, return false, else true.
             * </ol>
             */
            public final boolean await(long time, TimeUnit unit)
                    throws InterruptedException {
                long nanosTimeout = unit.toNanos(time);
                if (Thread.interrupted())
                    throw new InterruptedException();
                Node node = addConditionWaiter();
                int savedState = fullyRelease(node);
                final long deadline = System.nanoTime() + nanosTimeout;
                boolean timedout = false;
                int interruptMode = 0;
                while (!isOnSyncQueue(node)) {
                    if (nanosTimeout <= 0L) {
                        timedout = transferAfterCancelledWait(node);
                        break;
                    }
                    if (nanosTimeout >= spinForTimeoutThreshold)
                        LockSupport.parkNanos(this, nanosTimeout);
                    if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                        break;
                    nanosTimeout = deadline - System.nanoTime();
                }
                if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                    interruptMode = REINTERRUPT;
                if (node.nextWaiter != null)
                    unlinkCancelledWaiters();
                if (interruptMode != 0)
                    reportInterruptAfterWait(interruptMode);
                return !timedout;
            }
    
            //  support for instrumentation
    
            /**
             * Returns true if this condition was created by the given
             * synchronization object.
             *
             * @return {@code true} if owned
             */
            final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
                return sync == AbstractQueuedSynchronizer.this;
            }
    
            /**
             * Queries whether any threads are waiting on this condition.
             * Implements {@link AbstractQueuedSynchronizer#hasWaiters(ConditionObject)}.
             *
             * @return {@code true} if there are any waiting threads
             * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
             *         returns {@code false}
             */
            protected final boolean hasWaiters() {
                if (!isHeldExclusively())
                    throw new IllegalMonitorStateException();
                for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                    if (w.waitStatus == Node.CONDITION)
                        return true;
                }
                return false;
            }
    
            /**
             * Returns an estimate of the number of threads waiting on
             * this condition.
             * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength(ConditionObject)}.
             *
             * @return the estimated number of waiting threads
             * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
             *         returns {@code false}
             */
            protected final int getWaitQueueLength() {
                if (!isHeldExclusively())
                    throw new IllegalMonitorStateException();
                int n = 0;
                for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                    if (w.waitStatus == Node.CONDITION)
                        ++n;
                }
                return n;
            }
    
            /**
             * 得到同步队列当中所有在等待的Thread集合
             */
            protected final Collection<Thread> getWaitingThreads() {
                if (!isHeldExclusively())
                    throw new IllegalMonitorStateException();
                ArrayList<Thread> list = new ArrayList<Thread>();
                for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                    if (w.waitStatus == Node.CONDITION) {
                        Thread t = w.thread;
                        if (t != null)
                            list.add(t);
                    }
                }
                return list;
            }
        }
    
        /**
         * Setup to support compareAndSet. We need to natively implement
         * this here: For the sake of permitting future enhancements, we
         * cannot explicitly subclass AtomicInteger, which would be
         * efficient and useful otherwise. So, as the lesser of evils, we
         * natively implement using hotspot intrinsics API. And while we
         * are at it, we do the same for other CASable fields (which could
         * otherwise be done with atomic field updaters).
         * unsafe魔法类,直接绕过虚拟机内存管理机制,修改内存
         */
        private static final Unsafe unsafe = Unsafe.getUnsafe();
        private static final long stateOffset;
        private static final long headOffset;
        private static final long tailOffset;
        private static final long waitStatusOffset;
        private static final long nextOffset;
    
        static {
            try {
                stateOffset = unsafe.objectFieldOffset
                        (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
                headOffset = unsafe.objectFieldOffset
                        (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
                tailOffset = unsafe.objectFieldOffset
                        (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
                waitStatusOffset = unsafe.objectFieldOffset
                        (Node.class.getDeclaredField("waitStatus"));
                nextOffset = unsafe.objectFieldOffset
                        (Node.class.getDeclaredField("next"));
    
            } catch (Exception ex) { throw new Error(ex); }
        }
    
        /**
         * CAS 修改头部节点指向. 并发入队时使用.
         */
        private final boolean compareAndSetHead(Node update) {
            return unsafe.compareAndSwapObject(this, headOffset, null, update);
        }
    
        /**
         * CAS 修改尾部节点指向. 并发入队时使用.
         */
        private final boolean compareAndSetTail(Node expect, Node update) {
            return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
        }
    
        /**
         * CAS 修改信号量状态.
         */
        private static final boolean compareAndSetWaitStatus(Node node,
                                                             int expect,
                                                             int update) {
            return unsafe.compareAndSwapInt(node, waitStatusOffset,
                    expect, update);
        }
    
        /**
         * 修改节点的后继指针.
         */
        private static final boolean compareAndSetNext(Node node,
                                                       Node expect,
                                                       Node update) {
            return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
        }
    }
    View Code
    AbstractOwnableSynchronizer.java
    public abstract class AbstractOwnableSynchronizer implements java.io.Serializable {
        private static final long serialVersionUID = 3737899427754241961L;
    
        protected AbstractOwnableSynchronizer() { }
        /**
         * 独占模式同步器的当前持有线程.
         * transient关键字表示属性不参与序列化
         */
        private transient Thread exclusiveOwnerThread;
    
        protected final void setExclusiveOwnerThread(Thread thread) {
            exclusiveOwnerThread = thread;
        }
        protected final Thread getExclusiveOwnerThread() {
            return exclusiveOwnerThread;
        }
    }
    View Code

     

    
    
    
    
    
    
    
    
    
     

     

  • 相关阅读:
    通过xshell在本地win主机和远程linux主机传输文件
    CentOS7.4搭建ftp服务
    CentOS7.4中配置jdk环境
    spring AOP学习笔记
    java代码连接oracle数据库的方法
    通过xshell上传和下载文件
    java设计模式简述
    本地项目文件通过git提交到GitHub上
    centos7中oracle数据库安装和卸载
    centos7远程服务器中redis的安装与java连接
  • 原文地址:https://www.cnblogs.com/qianbing/p/12588556.html
Copyright © 2011-2022 走看看