AQS -- 公平锁实现上锁原理

public final void acquire(int arg) {
        /**
         * tryAcquire(arg): 尝试获取锁
         * acquireQueued :加入队列
         */
        if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

    /**
     * 尝试加锁
     * @param acquires
     * @return
     */
    protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        //获取lock对象锁上的状态
        int c = getState();
        // 表示没有其他线程占用,即锁(指state这个标志位)是自由状态的。
        if (c == 0) {
            /**
             * 看是否需要排队,如果不需要排队,则cas抢锁
             */
            if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                // 设置当前线程为已经拥有锁的线程
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        /**
         * 如果state已经被修改,说明有线程已上锁,再看上锁线程是否就是当前线程,如果是当前线程,则可重入
         */
        else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            if (nextc < 0)
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }

    /**
     * 判断自己是否需要排队
     * @return
     */
    public final boolean hasQueuedPredecessors() {
        /**
         *
         */
        AbstractQueuedSynchronizer.Node t = tail;
        AbstractQueuedSynchronizer.Node h = head;
        AbstractQueuedSynchronizer.Node s;
        return h != t &&
                ((s = h.next) == null || s.thread != Thread.currentThread());
    }

    /**
     * 将当前节点放入到队列当中
     * @param mode
     * @return
     */
    private AbstractQueuedSynchronizer.Node addWaiter(AbstractQueuedSynchronizer.Node mode) {
        AbstractQueuedSynchronizer.Node node = new AbstractQueuedSynchronizer.Node(Thread.currentThread(), mode);

        AbstractQueuedSynchronizer.Node pred = tail;
        /**
         * 队尾不等于null说明队列已经初始化了,那么只需要将新的节点排在后面,然后改成新的队尾即可
         */
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        /**
         * 队列没有初始化,进行初始化即可
         *
         * 第一个线程因为在aqs队列没有初始化时获取了锁,那么之后来的第二个线程需要排队,这个时候进行了初始化
         */
        enq(node);
        return node;
    }

    /**
     * 初始化队列
     * @param node
     * @return
     */
    private AbstractQueuedSynchronizer.Node enq(final AbstractQueuedSynchronizer.Node node) {
        // 死循环
        for (;;) {
            AbstractQueuedSynchronizer.Node t = tail;
            // 第一次,队列没有初始化时,没有一个节点。
            if (t == null) { 
                // 构造了一个新的节点,prev = null ,next = null ,thread = null .
                if (compareAndSetHead(new AbstractQueuedSynchronizer.Node()))
                    // 设置首尾都是 上面的那个node
                    tail = head;
                /**
                 * 之后,队列已经有了一个节点了,将当前的节点挂在第一个节点后面,并且设置aqs队列的尾部为当前节点
                  */    
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

参考链接:https://blog.csdn.net/java_lyvee/article/details/98966684

你可能感兴趣的:(jdk)