Java源码阅读(五)—— AbstractQueuedSynchronizer

背景和作用

在同步组件的实现中,AQS是核心部分,同步组件的实现者通过使用AQS提供的模板方法实现同步组件语义,AQS则实现了对同步状态的管理,以及对阻塞线程进行排队,等待通知等等一些底层的实现处理。AQS的核心也包括了这些方面:同步队列,独占式锁的获取和释放,共享锁的获取和释放以及可中断锁,超时等待锁获取这些特性的实现。

AQS


public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {

    /**
     * Empty constructor for use by subclasses.
     */
    protected AbstractOwnableSynchronizer() { }

    /**
     * The current owner of exclusive mode synchronization.
     */
    //独占模式下的线程
    private transient Thread exclusiveOwnerThread;

    // getter、setter
    protected final void setExclusiveOwnerThread(Thread thread) {
        exclusiveOwnerThread = thread;
    }

    protected final Thread getExclusiveOwnerThread() {
        return exclusiveOwnerThread;
    }
}



AQS#Node


        /** Marker to indicate a node is waiting in shared mode */
        static final Node SHARED = new Node();

        /** Marker to indicate a node is waiting in exclusive mode */
        static final Node EXCLUSIVE = null;

        /** waitStatus value to indicate thread has cancelled */
        static final int CANCELLED =  1;

        /** waitStatus value to indicate successor's thread needs unparking */
        static final int SIGNAL    = -1;

        /** waitStatus value to indicate thread is waiting on condition */
        static final int CONDITION = -2;

        /**
         * waitStatus value to indicate the next acquireShared should
         * unconditionally propagate
         */
        static final int PROPAGATE = -3;

        // 该变量主要记录线程的状态,确保线程是有效的,CANCELLED、SIGNAL、CONDITION、PROPAGATE
        volatile int waitStatus;

        volatile Node prev;

        volatile Node next;

        volatile Thread thread;

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

AbstractQueuedSynchronizer

AQS使用CLH队列来实现线程排队的功能,CLH队列的原理是一个双向链表,每个链表由Node节点组成,Node节点保存prev和next两个指针,并保存指向线程的指针。

/**
     * Head of the wait queue, lazily initialized.  Except for
     * initialization, it is modified only via method setHead.  Note:
     * If head exists, its waitStatus is guaranteed not to be
     * CANCELLED.
     */
    // 记录CLH的头部节点,目的是配合tail实现出队操作
    private transient volatile Node head;

    /**
     * Tail of the wait queue, lazily initialized.  Modified only via
     * method enq to add new wait node.
     */
    // 记录CLH的尾部节点
    private transient volatile Node tail;

    /**
     * The synchronization state.
     */
    // 用于记录加锁的次数,同一个线程加两次锁,则state = 2
    private volatile int state;

   /**
     * Inserts node into queue, initializing if necessary. See picture above.
     * @param node the node to insert
     * @return node's predecessor
     */
    // 入队操作
    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;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }
posted @ 2019-05-15 20:14  清泉白石  阅读(388)  评论(0编辑  收藏  举报