AbstractQueuedSynchronizer

/**自旋锁,CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,
 * 它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋。
 *
 * 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架。
 *
 * 利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础。
 *
 * 该同步器即可以作为排他模式也可以作为共享模式,当它被定义为一个排他模式时,
 * 其他线程对其的获取就被阻止,而共享模式对于多个线程获取都可以成功。
 */

public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {

    private static final long serialVersionUID = 7373984972572414691L;

    protected AbstractQueuedSynchronizer() { }

    //保存着线程引用和线程状态的容器,每个线程对同步器的访问,都可以看做是队列中的一个节点。
    static final class Node {

        //共享模式
        static final Node SHARED = new Node();

        //独占模式
        static final Node EXCLUSIVE = null;

        //表示当前的线程被取消
        static final int CANCELLED =  1;

        //表示当前节点的后继节点包含的线程需要运行,也就是unpark
        static final int SIGNAL    = -1;

        //表示当前节点在等待condition,也就是在condition队列中
        static final int CONDITION = -2;
        /**
         * waitStatus value to indicate the next acquireShared should
         * unconditionally propagate
         */
        //表示当前场景下后续的acquireShared能够得以执行
        static final int PROPAGATE = -3;

        // 结点状态
        volatile int waitStatus;

        //前驱结点
        volatile Node prev;

        //后继结点
        volatile Node next;

        //如队列的当前线程
        volatile Thread thread;

        //存储condition队列中的后继节点
        Node nextWaiter;

        // 结点是否在共享模式下等待
        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;

    protected final int getState() {
        return state;
    }

    protected final void setState(int newState) {
        state = newState;
    }
    //原子操作更新同步状态值
    protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

    //自旋时间
    static final long spinForTimeoutThreshold = 1000L;

    private Node enq(final Node node) {
        for (;;) { //无限循环,确保结点能够成功入队列
            //保存尾结点
            Node t = tail;
            if (t == null) { //尾结点为空,初始化
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else { //尾结点非空,已经初始化
                node.prev = t;
                if (compareAndSetTail(t, node)) {//原子操作将尾结点更新设置为node
                    t.next = node;
                    return t;//返回尾结点
                }
            }
        }
    }

    //快速添加的方式往sync queue尾部添加结点
    private Node addWaiter(Node mode) {
        //生成结点
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
        //保存尾结点
        Node pred = tail;
        if (pred != null) {//尾结点非空,已经初始化
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {//原子操作将尾结点更新设置为node
                pred.next = node;
                return node;//返回新生成的结点
            }
        }
        enq(node);// 尾结点为空,或者是compareAndSetTail操作失败,则入队列
        return node;
    }

    private void setHead(Node node) {
        head = node;
        node.thread = null;
        node.prev = null;
    }

    //唤醒node后继结点的线程
    private void unparkSuccessor(Node node) {
        int ws = node.waitStatus;
        if (ws < 0)
            compareAndSetWaitStatus(node, ws, 0);//比较并且设置结点等待状态为0
        Node s = node.next;
        if (s == null || s.waitStatus > 0) {//后继结点为空或者其等待状态大于0,即为CANCELLED
            s = null;
            // 从尾结点开始从后往前开始遍历
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0) 找到等待状态小于等于0的结点,找到最前的状态小于等于0的结点
                    s = t;
        }
        if (s != null)//该结点不为空,释放线程许可
            LockSupport.unpark(s.thread);
    }

    private void doReleaseShared() {
        for (;;) {
            Node h = head;
            if (h != null && h != tail) {// 头结点不为空并且头结点不为尾结点
                int ws = h.waitStatus;
                if (ws == Node.SIGNAL) {// 状态为SIGNAL
                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))//设置h.waitStatus = 0
                        continue;            // loop to recheck cases
                    unparkSuccessor(h);//唤醒后继结点
                }
                else if (ws == 0 &&
                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                    continue;                // loop on failed CAS
            }
            if (h == head)                   // loop if head changed
                break;
        }
    }

    private void setHeadAndPropagate(Node node, int propagate) {
        Node h = head; // Record old head for check below
        setHead(node);
        if (propagate > 0 || h == null || h.waitStatus < 0 ||
            (h = head) == null || h.waitStatus < 0) {
            Node s = node.next;
            if (s == null || s.isShared())// 后继为空或者为共享模式
                doReleaseShared();// 以共享模式进行释放
        }
    }

    //取消继续获取锁
    private void cancelAcquire(Node node) {
        if (node == null)
            return;
        node.thread = null;
        Node pred = node.prev;
        while (pred.waitStatus > 0)//找到node前驱结点中最近的一个不为CANCELLED状态的结点
            node.prev = pred = pred.prev;
        Node predNext = pred.next;
        node.waitStatus = Node.CANCELLED;

        // node结点为尾结点,则设置尾结点为pred结点
        if (node == tail && compareAndSetTail(node, pred)) {
            compareAndSetNext(pred, predNext, null);
        } else {//node结点不为尾结点,或者比较设置不成功
            // 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;
                //后继结点不为空并且状态小于等于0
                if (next != null && next.waitStatus <= 0)
                    compareAndSetNext(pred, predNext, next);//比较并设置pred.next = next
            } else {
                unparkSuccessor(node);//uppark node后继结点
            }

            node.next = node; // help GC
        }
    }

    //获取锁失败后,检查并且更新结点状态
    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
        int ws = pred.waitStatus;//前驱结点的状态
        if (ws == Node.SIGNAL) //状态为SIGNAL = -1
            //可以进行park操作
            return true;
        if (ws > 0) { //状态为CANCELLED = 1
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);//找到pred结点前面最近的一个状态不为CANCELLED的结点
            pred.next = node;
        } else {
            //比较并设置前驱结点的状态为SIGNAL
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;// 不能进行park操作
    }

    static void selfInterrupt() {
        Thread.currentThread().interrupt();
    }

    private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);//挂起线程
        return Thread.interrupted();//返回线程是否被中断
    }

    /**
    * ① 判断结点的前驱是否为head并且是否成功获取(资源)。
   * ② 若步骤①均满足,则设置结点为head,之后会判断是否finally模块,然后返回。
   * ③ 若步骤①不满足,则判断是否需要park当前线程,是否需要park当前线程的逻辑是判断结点的前驱结点的状态是否为SIGNAL,若是,则park当前结点,否则,不进行park操作。
   * ④ 若park了当前线程,之后某个线程对本线程unpark后,并且本线程也获得机会运行。那么,将会继续进行步骤①的判断。
    */
    //sync结点在独占且忽略中断模式下获取锁
    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;//中断标志
            for (;;) {
                //获取node结点的前驱结点
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) { //前驱为头结点并且成功获得锁
                    setHead(node);//将当前结点设置为头节点
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                //只有当该节点的前驱结点的状态为SIGNAL时,才可以对该结点所封装的线程进行park操作
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

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

    //以独占的方式获取锁,对中断不敏感
    public final void acquire(int arg) {
        //以独占的方式tryAcquire()尝试获取锁
        //如果获取不到,将当前线程构造成节点Node并加入sync队列
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

    public final void acquireInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (!tryAcquire(arg))
            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 boolean release(int arg) {
        if (tryRelease(arg)) {//释放成功
            Node h = head;
            //头结点不为空且状态不为0
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);//唤醒头结点的后继结点
            return true;
        }
        return false;
    }

    public final void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0)
            doAcquireShared(arg);
    }

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

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

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


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

    public class ConditionObject implements Condition, java.io.Serializable {
        private static final long serialVersionUID = 1173984872572414699L;
        /** First node of condition queue. */
        //condition队列头结点
        private transient Node firstWaiter;
        /** Last node of condition queue. */
        //condition队列尾结点
        private transient Node lastWaiter;

        public ConditionObject() { }

        //添加新的waiter到wait队列
        private Node addConditionWaiter() {
            //保存尾结点
            Node t = lastWaiter;
            // If lastWaiter is cancelled, clean out.
            if (t != null && t.waitStatus != Node.CONDITION) {// 尾结点不为空,并且尾结点的状态不为CONDITION
                unlinkCancelledWaiters();//清除状态为不是CONDITION的结点
                t = lastWaiter;// 将最后一个结点重新赋值给t
            }
            Node node = new Node(Thread.currentThread(), Node.CONDITION);
            if (t == null)// 尾结点为空
                firstWaiter = node;//设置头结点为node
            else
                t.nextWaiter = node; //设置尾结点nextWaiter域为node结点
            lastWaiter = node;//尾结点指向node
            return node;
        }

        /**
         * Removes and transfers nodes until hit non-cancelled one or
         * null. Split out from signal in part to encourage compilers
         * to inline the case of no waiters.
         * @param first (non-null) the first node on condition queue
         */
        private void doSignal(Node first) {
            do {
                if ( (firstWaiter = first.nextWaiter) == null)//该结点的nextWaiter域为null,设置尾结点为null
                    lastWaiter = null;
                first.nextWaiter = null;
            } while (!transferForSignal(first) &&
                     (first = firstWaiter) != null);// 将结点从condition队列转移到sync队列失败并且condition队列中的头结点不为空,一直循环
        }

        /**
         * Removes and transfers all nodes.
         * @param first (non-null) the first node on condition queue
         */
        private void doSignalAll(Node first) {
            lastWaiter = firstWaiter = null;
            do {
                Node next = first.nextWaiter;
                first.nextWaiter = null;
                transferForSignal(first);// 将first结点从condition队列转移到sync队列
                first = next;
            } while (first != null);
        }

        //清除状态不是CONDITION的结点
        private void unlinkCancelledWaiters() {
            //保存condition队列头结点
            Node t = firstWaiter;
            Node trail = null;
            while (t != null) {
                Node next = t.nextWaiter;
                if (t.waitStatus != Node.CONDITION) {// t结点的状态不为CONDTION状态
                    t.nextWaiter = null;// 设置t节点的nextWaiter域为空
                    if (trail == null)
                        firstWaiter = next;// 重新设置condition队列的头结点
                    else
                        trail.nextWaiter = next;
                    if (next == null)
                        lastWaiter = trail;// 设置condition队列的尾结点
                }
                else // t结点的状态为CONDTION状态
                    trail = t; // 设置trail结点
                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;
            //signal操作会将Node从Condition队列中拿出并且放入到sync等待队列中去,在不在AQS等待队列就看signal是否执行了
            //如果不在AQS等待队列中,就park当前线程,如果在,就退出循环
            while (!isOnSyncQueue(node)) {
                LockSupport.park(this);// 阻塞当前线程
                if (Thread.interrupted())// 当前线程被中断
                    interrupted = true;
            }
            // 自旋等待尝试再次获取锁,调用acquireQueued方法
            if (acquireQueued(node, savedState) || interrupted)
                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);
        }
    }


}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值