多线程(八)AbstractOwnableSynchronizer 和 AbstractQueuedSynchronizer

1、AbstractOwnableSynchronizer,设置 和 获取独占锁的拥有者线程。

可以由线程以独占方式拥有的同步器。此类为创建锁和相关同步器(伴随着所有权的概念)提供了基础。AbstractOwnableSynchronizer 类本身不管理或使用此信息。但是,子类和工具可以使用适当维护的值帮助控制和监视访问以及提供诊断。

public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {

    private static final long serialVersionUID = 3737899427754241961L;

    protected AbstractOwnableSynchronizer() { }

/*    互斥模式同步下的当前线程 */
    private transient Thread exclusiveOwnerThread;

/*    设置当前拥有独占访问的线程。锁的拥有线程,null 参数表示没有线程拥有访问。
      此方法不另外施加任何同步或 volatile 字段访问。
     */
    protected final void setExclusiveOwnerThread(Thread t) {
        exclusiveOwnerThread = t;
    }

/*    返回由 setExclusiveOwnerThread 最后设置的线程;
      如果从未设置,则返回 null。
      此方法不另外施加任何同步或 volatile 字段访问。 
     */
    protected final Thread getExclusiveOwnerThread() {
        return exclusiveOwnerThread;
    }
}

2、AbstractQueuedSynchronizer

1>. AQS -- 指AbstractQueuedSynchronizer类。

    AQS是java中管理“锁”的抽象类,锁的许多公共方法都是在这个类中实现。AQS是独占锁(例如ReentrantLock)和共享锁(例如Semaphore)的公共父类。

2>. 队列

    队列是AQS中“等待锁”的线程队列。在多线程中,为了保护竞争资源不被多个线程同时操作而起来错误,我们常常需要通过锁来保护这些资源。在独占锁中,竞争资源在一个时间点只能被一个线程锁访问;而其它线程则需要等待。队列就是管理这些“等待锁”的线程的队列。
    队列是一个非阻塞的 FIFO 队列。也就是说往里面插入或移除一个节点的时候,在并发条件下不会阻塞,而是通过自旋锁和 CAS 保证节点插入和移除的原子性。

为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量、事件,等等)提供一个框架。此类的设计目标是成为依靠单个原子 int 值来表示状态的大多数同步器的一个有用基础。子类必须定义更改此状态的受保护方法,并定义哪种状态对于此对象意味着被获取或被释放。假定这些条件之后,此类中的其他方法就可以实现所有排队和阻塞机制。子类可以维护其他状态字段,但只是为了获得同步而只追踪使用 getState()setState(int)compareAndSetState(int, int) 方法来操作以原子方式更新的 int 值。

应该将子类定义为非公共内部帮助器类,可用它们来实现其封闭类的同步属性。类 AbstractQueuedSynchronizer 没有实现任何同步接口。而是定义了诸如 acquireInterruptibly(int) 之类的一些方法,在适当的时候可以通过具体的锁和相关同步器来调用它们,以实现其公共方法。

此类支持默认的独占 模式和共享 模式之一,或者二者都支持。处于独占模式下时,其他线程试图获取该锁将无法取得成功。在共享模式下,多个线程获取某个锁可能(但不是一定)会获得成功。此类并不“了解”这些不同,除了机械地意识到当在共享模式下成功获取某一锁时,下一个等待线程(如果存在)也必须确定自己是否可以成功获取该锁。处于不同模式下的等待线程可以共享相同的 FIFO 队列。通常,实现子类只支持其中一种模式,但两种模式都可以在(例如)ReadWriteLock 中发挥作用。只支持独占模式或者只支持共享模式的子类不必定义支持未使用模式的方法。

此类通过支持独占模式的子类定义了一个嵌套的 AbstractQueuedSynchronizer.ConditionObject 类,可以将这个类用作 Condition 实现。isHeldExclusively() 方法将报告同步对于当前线程是否是独占的;使用当前 getState() 值调用 release(int) 方法则可以完全释放此对象;如果给定保存的状态值,那么 acquire(int) 方法可以将此对象最终恢复为它以前获取的状态。没有别的 AbstractQueuedSynchronizer 方法创建这样的条件,因此,如果无法满足此约束,则不要使用它。AbstractQueuedSynchronizer.ConditionObject 的行为当然取决于其同步器实现的语义。

此类为内部队列提供了检查、检测和监视方法,还为 condition 对象提供了类似方法。可以根据需要使用用于其同步机制的 AbstractQueuedSynchronizer 将这些方法导出到类中。

此类的序列化只存储维护状态的基础原子整数,因此已序列化的对象拥有空的线程队列。需要可序列化的典型子类将定义一个 readObject 方法,该方法在反序列化时将此对象恢复到某个已知初始状态。

(1)AbstractQueuedSynchronizer类中有个静态的内部类Node,作为阻塞队列里面的每个节点

/* Wait queue node class. */
    static final class Node {   
        static final Node SHARED = new Node();    //共享状态
        static final Node EXCLUSIVE = null;    //互斥状态
        static final int CANCELLED =  1;    //等待状态的值,1表示线程被取消
        static final int SIGNAL    = -1;     //等待状态的值,-1表示接下来的线程需要唤醒(信号)
        static final int CONDITION = -2;       //等待状态的值,-2表示线程需要等待条件
        static final int PROPAGATE = -3;      //WaistStand值指示下一个获取应该无条件传播
        //WaistStand值为0这里没写,为0也算是一种状态,但不是上面所有的,表示没有被任何锁拥有
        volatile int waitStatus;    //等待状态
        volatile Node prev;    //前一个node     
        volatile Node next;    //后一个node
        volatile Thread thread;    //在node里面的线程
        Node nextWaiter;    //下一个正处在等待条件的node
        /**如果在等待node在共享模式下返回true*/
        final boolean isShared() {
            return nextWaiter == SHARED;}
        /**返回前一个祖先node。如果为空返回空指针异常*/
        final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }
        Node() {}    //用于建立初始标记或共享标记
        Node(Thread thread, Node mode) {     // 给线程添加等待模型,生成node
            this.nextWaiter = mode;
            this.thread = thread;
        }
        Node(Thread thread, int waitStatus) { // 给线程添加等待条件,生成node
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }

 (2)对Node的一些CAS操作。

//对node进行CAS操作
    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进行原子更新。如果当前状态值等于预期值,则以原子方式将同步状态设置为给定的更新值。*/
    protected final boolean compareAndSetState(int expect, int update) {
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }
    private final boolean compareAndSetHead(Node update) {
        return unsafe.compareAndSwapObject(this, headOffset, null, update);
    }
    private final boolean compareAndSetTail(Node expect, Node update) {
        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
    }
    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);
    }

 (3)还有一个内部类ConditionObject实现了Condition接口

   public class ConditionObject implements Condition, java.io.Serializable {
        private static final long serialVersionUID = 1173984872572414699L;
        private transient Node firstWaiter;    //队列头的等待者
        private transient Node lastWaiter;    //队列尾的等待者
        public ConditionObject() { }
        //将当前线程添加条件等待,放在等待队列的尾部
        private Node addConditionWaiter() {
            Node t = lastWaiter;
            if (t != null && t.waitStatus != Node.CONDITION) {
                unlinkCancelledWaiters();
                t = lastWaiter;
            }
            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 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);
        }

        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();
        }

        private static final int REINTERRUPT =  1;
        private static final int THROW_IE    = -1;

        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);
                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);
        }

        public final long awaitNanos(long nanosTimeout)
                throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            Node node = addConditionWaiter();
            int savedState = fullyRelease(node);
            long lastTime = System.nanoTime();
            int interruptMode = 0;
            while (!isOnSyncQueue(node)) {
                if (nanosTimeout <= 0L) {
                    transferAfterCancelledWait(node);
                    break;
                }
                LockSupport.parkNanos(this, nanosTimeout);
                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                    break;

                long now = System.nanoTime();
                nanosTimeout -= now - lastTime;
                lastTime = now;
            }
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null)
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
            return nanosTimeout - (System.nanoTime() - lastTime);
        }

        public final boolean awaitUntil(Date deadline)
                throws InterruptedException {
            if (deadline == null)
                throw new NullPointerException();
            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;
        }

        public final boolean await(long time, TimeUnit unit)
                throws InterruptedException {
            if (unit == null)
                throw new NullPointerException();
            long nanosTimeout = unit.toNanos(time);
            if (Thread.interrupted())
                throw new InterruptedException();
            Node node = addConditionWaiter();
            int savedState = fullyRelease(node);
            long lastTime = System.nanoTime();
            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;
                long now = System.nanoTime();
                nanosTimeout -= now - lastTime;
                lastTime = now;
            }
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null)
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
            return !timedout;
        }

        final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
            return sync == AbstractQueuedSynchronizer.this;
        }

        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;
        }

        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;
        }

        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;
        }
    }
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer
    implements java.io.Serializable {
    private static final long serialVersionUID = 7373984972572414691L;
    protected AbstractQueuedSynchronizer() { }
/*  等待队列头,懒加载 ,除了初始化,它只通过方法setHead()修改
    注意:如果头存在,原来的头它的等待状态不保证被取消 */
    private transient volatile Node head;
/*  等待队列尾巴,懒加载,仅通过方法enq()以添加新的等待节点修改。*/
    private transient volatile Node tail;
/*    同步的状态*/
    private volatile int state;
/*    返回同步的状态*/
    protected final int getState() {
        return state;    }
/*    设置同步的状态*/
    protected final void setState(int newState) {
        state = newState;}
/*   用纳秒旋转而不是用过时的挂起。 粗略估计足以在非常短的超时时间内提高响应性。 */
    static final long spinForTimeoutThreshold = 1000L;

/*    将node插入队尾,返回插入的node的前一个*/
    private Node enq(final Node node) {
        for (;;) {
            Node t = tail;    //t指向tail节点
            if (t == null) { // 如果为空则必须初始化队头
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {    //进行双向关联,先向前关联
                node.prev = t;    //要插入的node这个的前面指向t
                if (compareAndSetTail(t, node)) {
                    t.next = node;    //t的下一个指向要插入的node,进行双向关联。
                    return t;
                }
            }
        }
    }
/*    获取独占锁:先尝试获取,锁没有被占用,则直接获取,加入队列尾部,阻塞等待直到获取锁*/
    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&    //先尝试获取,锁没有被占用,则直接获取返回true,否则返回false
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))    //如果没有获取锁,则加入尾部,并阻塞该锁,如果被中断,则执行下面的selfInterrupt自我中断
            selfInterrupt();
    }
/*    获取共享锁,先尝试获取,<0说明获取不到,再次获取*/
    public final void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0)
            doAcquireShared(arg);
    }
/*    试着释放当前线程持有的独占锁并唤醒后继节点*/
    public final boolean release(int arg) {
        if (tryRelease(arg)) {//试着释放当前线程持有的锁
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);// 唤醒后继节点
            return true;
        }
        return false;
    }                


/*    对当前队列和你指定的mode(Node.EXCLUSIVE 和Node.SHARED )放入到node节点中,并加入队尾,
        返回要插入的node ,即新node节点*/
    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        Node pred = tail;    //pred为队尾
        if (pred != null) {    //进行关联
            node.prev = pred;    
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);    //如果队列为空,就用enq()创建队列进行添加node
        return node;
    }

/*    设置node到队列的头,去排队,返回当前node,头节点只是一个节点,里面没有线程
    注意:就算你添加的node是全的,进入队头线程就会被置为空*/
    private void setHead(Node node) {
        head = node;
        node.thread = null;
        node.prev = null;
    }
/*    唤醒node它的下一个,如果下一个存在就唤醒,如果下个不存在就从后向前找到离你传的node最近的被阻塞的node唤醒*/
    private void unparkSuccessor(Node node) {
        int ws = node.waitStatus;    //看当前的node的状态
        if (ws < 0) compareAndSetWaitStatus(node, ws, 0);    //如果被阻塞,置为0

        Node s = node.next;    //当前node的下一个
        if (s == null || s.waitStatus > 0) {    //>0表示线程被取消,被取消后从尾部找能离node近的唤醒
            s = null;
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0)    //从后向前查找需要唤醒的线程,找到离你传的node最近的需要信号的唤醒。
                    s = t;    }
        if (s != null)
            LockSupport.unpark(s.thread);    //唤醒
    }
/*    释放共享模式,从头部开始的第一个需要信号(被唤醒)的node释放,确保传播。
    注意:对于互斥模式,如果需要被唤醒,相当于调用unpackSuccessor()的头部*/
    private void doReleaseShared() {
        for (;;) {
            Node h = head;    //转换到头部
            if (h != null && h != tail) {    //如果节点大于1个,一直循环
                int ws = h.waitStatus;    //获取头部状态
                if (ws == Node.SIGNAL){    //如果头部是刚好需要信号(唤醒)
                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))//如果比较一样,将状态置为0
                        continue;            // loop to recheck cases
                    unparkSuccessor(h);    //成功,释放head后继节点
                }
                else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                    continue; // 成功的 CAS,如果成功则转为传播模式,继续循环,。
            }
            if (h == head)                   //只有head,返回
                break;
        }
    }

/*    设置队列头部,并且检查后继节点是否处在共享模式的的阻塞中,并释放后继阻塞的node节点。
     * @param node 为将要设置为头node
     * @param propagate  试图在共享模式下获取对象状态。*/
    private void setHeadAndPropagate(Node node, int propagate) {
        Node h = head; // 为下面的检查记录老的head节点
        setHead(node);
        //状态>0或者,老head为空或者,老head为阻塞,只要老head不是取消
        if (propagate > 0 || h == null || h.waitStatus < 0) {
            Node s = node.next;
            if (s == null || s.isShared())//s == null说明只有head,或者是共享模式
                doReleaseShared();    //释放共享模式的阻塞node
        }
    }

/*将传入的节点,取消,并组成新的链,并跳过取消的前驱node,如果直到头节点,那么就唤醒node的下一个阻塞node*/
    private void cancelAcquire(Node node) {
        if (node == null)
            return;
        node.thread = null;
        Node pred = node.prev;
        while (pred.waitStatus > 0)    //跳过取消的前驱node
            node.prev = pred = pred.prev;
        Node predNext = pred.next;
        node.waitStatus = Node.CANCELLED;    //设置为取消
        if (node == tail && compareAndSetTail(node, pred)) {    //若为尾部,则置为空
            compareAndSetNext(pred, predNext, null);
        } else {
            int ws;
            if (pred != head &&((ws = pred.waitStatus) == Node.SIGNAL ||
                 (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
                pred.thread != null) {    //只要pred的不为头节点和处于阻塞状态
                Node next = node.next;
                if (next != null && next.waitStatus <= 0)
                    compareAndSetNext(pred, predNext, next);    //pred链接node取消后的node
            } else {
                unparkSuccessor(node);    //为头唤醒node的下一个阻塞node
            }
            node.next = node; // 手动 GC
        }
    }
/*    如果node的前驱时信号状态则返回true,否则返回false,且在返回false时,将他的前驱置为信号状态或阻塞状态*/
    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
        int ws = pred.waitStatus;
        if (ws == Node.SIGNAL)
            return true;
        if (ws > 0) {
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);    //查找它的前驱直到它处于<0时
            pred.next = node;
        } else {    //<0则置为信号(被唤醒)
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;
    }
/*    设置当前运行的线程中断flag*/
    private static void selfInterrupt() {  Thread.currentThread().interrupt();}
/*    阻塞当前node,并查看中断状态并清除中断flag*/
    private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
    }
/*    返回:等待中的是否被中断,被中断返回true,没有被中断则返回false
     */
        final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            // interrupted表示在队列的调度中,当前线程在休眠时,有没有被中断过
            boolean interrupted = false;
            for (;;) {
                // 获取上一个节点,node是当前线程对应的节点,这里就意味着获取上一个等待锁的线程
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
            /*使用p==head表示当前线程前面的线程已经得到执行,来保证锁的公平性。
                如果当前线程是因为“线程被中断”而唤醒,那么显然就不是公平了*/
                    setHead(node);
                    p.next = null;                 // help GC
                    failed = false;
                    return interrupted;            // 只有在这里才能跳出死循环
                }
                if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }
/*     获取独占锁的可中断模式*/
    private void doAcquireInterruptibly(int arg) throws InterruptedException {
        // 创建"当前线程"的Node节点,且Node中记录的锁是"独占锁"类型;并将该节点添加到CLH队列末尾。
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {
            // 获取上一个节点。
            // 如果上一节点是CLH队列的表头,则"尝试获取独占锁"。
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
            // (上一节点不是CLH队列的表头) 当前线程一直等待,直到获取到独占锁。
            // 如果线程在等待过程中被中断过,则再次中断该线程(还原之前的中断状态)。
                if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);    //将当前线程node清除
        }
    }

    /**
     * Acquires in exclusive timed mode.
     *
     * @param arg the acquire argument
     * @param nanosTimeout max wait time
     * @return {@code true} if acquired
     */
    private boolean doAcquireNanos(int arg, long nanosTimeout)
        throws InterruptedException {
        long lastTime = System.nanoTime();
        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;
                }
                if (nanosTimeout <= 0)
                    return false;
                if (shouldParkAfterFailedAcquire(p, node) &&
                    nanosTimeout > spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                long now = System.nanoTime();
                nanosTimeout -= now - lastTime;
                lastTime = now;
                if (Thread.interrupted())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    /**
     * 获取共享锁的不中断模式
     * @param arg the acquire argument
     */
    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);
                    if (r >= 0) {
                        setHeadAndPropagate(node, r);
                        p.next = null; // help GC
                        if (interrupted)
                            selfInterrupt();
                        failed = false;
                        return;
                    }
                }
                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 {

        long lastTime = System.nanoTime();
        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;
                    }
                }
                if (nanosTimeout <= 0)
                    return false;
                if (shouldParkAfterFailedAcquire(p, node) &&
                    nanosTimeout > spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                long now = System.nanoTime();
                nanosTimeout -= now - lastTime;
                lastTime = now;
                if (Thread.interrupted())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    // Main exported methods,这些方法需要被重写,这里只定义了接口
    //尝试获取独占锁
    protected boolean tryAcquire(int arg) {throw new UnsupportedOperationException(); }
    //尝试释放独占锁
    protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); }
    //尝试获取共享锁
    protected int tryAcquireShared(int arg) { throw new UnsupportedOperationException();}
    //尝试释放共享锁
    protected boolean tryReleaseShared(int arg) { throw new UnsupportedOperationException(); }

    protected boolean isHeldExclusively() { throw new UnsupportedOperationException(); }
    //获取独占锁的中断模式
    public final void acquireInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())    //查看当前线程是否有中断flag,有的话,清除并抛出中断异常
            throw new InterruptedException();
        if (!tryAcquire(arg))    //尝试获取锁,如果失败,则调doAcquireInterruptibly独占锁的可中断模式
            doAcquireInterruptibly(arg);
    }

    public final boolean tryAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquire(arg) ||
            doAcquireNanos(arg, nanosTimeout);
    }

    public final void acquireSharedInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (tryAcquireShared(arg) < 0)
            doAcquireSharedInterruptibly(arg);
    }

    public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquireShared(arg) >= 0 ||
            doAcquireSharedNanos(arg, nanosTimeout);
    }

    public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) {
            doReleaseShared();
            return true;
        }
        return false;
    }

    // Queue inspection methods

    public final boolean hasQueuedThreads() {
        return head != tail;
    }

    public final boolean hasContended() {
        return head != null;
    }

    public final Thread getFirstQueuedThread() {
        // handle only fast path, else relay
        return (head == tail) ? null : fullGetFirstQueuedThread();
    }

    private Thread fullGetFirstQueuedThread() {
        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;
        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;
    }

    final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null &&
            (s = h.next)  != null &&
            !s.isShared()         &&
            s.thread != null;
    }

    public final boolean hasQueuedPredecessors() {
        // The correctness of this depends on head being initialized
        // before tail and on head.next being accurate if the current
        // thread is first in queue.
        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;
    }

    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;
    }

    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;
    }

    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;
    }

    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) {
        if (node.waitStatus == Node.CONDITION || node.prev == null)
            return false;
        if (node.next != null) // If has successor, it must be on queue
            return true;
        return findNodeFromTail(node);
    }

    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) {
        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;
    }

    final boolean transferAfterCancelledWait(Node node) {
        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
            enq(node);
            return true;
        }
        while (!isOnSyncQueue(node))
            Thread.yield();
        return false;
    }

    final int fullyRelease(Node node) {
        boolean failed = true;
        try {
            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

    public final boolean owns(ConditionObject condition) {
        if (condition == null)
            throw new NullPointerException();
        return condition.isOwnedBy(this);
    }

    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();
    }

    public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.getWaitingThreads();
    }

}

 现在大致了解下流程:

一般实现该类的是从Lock()开始,以共享锁(读锁)为例:

获取锁

1、lock()

2、acquireShared()

3、tryAcquireShared()在该类中没有实现,一般他的子类会实现。在该读锁实现类中,-1表示获取失败,1表示获取成功,获取成功就会运行,具体代码这里不描述了。

如果获取失败则会调doAcquireShared(),它的流程是这样的,现将当前线程加入到队尾,如果他的前一个节点是队头,则再调用tryAcquireShared()尝试获取,若获取成功则运行当前线程,如果获取失败则调用shouldParkAfterFailedAcquire(p, node)使他阻塞,在调用parkAndCheckInterrupt()看是否在阻塞的过程中被中断,如果被中断则中断。

释放锁:

锁获取后,运行完了就该释放了

1、unlock()

2、releaseShared()

3、tryReleaseShared()该类中没有实现,需要子类进行实现,尝试释放共享锁,要是可以释放,则用doReleaseShared()释放头节点的后面节点。不可以释放则不释放。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值