AQS源码的一点思考

/**
     * Acquires in exclusive uninterruptible mode for thread already in
     * queue. Used by condition wait methods as well as acquire.
     *
     * @param node the node
     * @param arg the acquire argument
     * @return {@code true} if interrupted while waiting
     */
    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            // 这里是一个自旋操作,用来进行获取锁或者进入阻塞的动作
            for (;;) {
                final Node p = node.predecessor();
                // 如果前驱节点为头节点(head,其实是一个虚节点,不关联任何线程),
                // 并且尝试加锁(tryAcquire)成功的话,讲当前节点设置为头节点(head)
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                // 如果当前节点的前驱节点不是头节点,或者是头节点但是没有抢到锁(被非公平锁抢占了)
                // 就会通过shouldParkAfterFailedAcquire判断当前节点是否需要将自己挂起,进入阻塞状态
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }
/**
     * 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;
        // 如果当前节点的前驱节点的waitStatus为Node.SIGNAL的话,
        // 就意味着当前节点需要进入阻塞状态,将自己挂起
        if (ws == Node.SIGNAL)
            /*
             * This node has already set status asking a release
             * to signal it, so it can safely park.
             */
            return true;
        if (ws > 0) {
            /*
             * Predecessor was cancelled. Skip over predecessors and
             * indicate retry.
             */
            // 如果当前节点的前驱节点的waitStatus>0的话,意味着前驱节点的waitStatus=CANCELLED,
            // 那么就要从前往后遍历,将CALCELLED的前驱节点都从链表中摘除
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
            /*
             * waitStatus must be 0 or PROPAGATE.  Indicate that we
             * need a signal, but don't park yet.  Caller will need to
             * retry to make sure it cannot acquire before parking.
             */
            // 如果前驱节点的waitStatus不是CANCELLED(1),也不是SIGNAL(-1),
            // 那就将当前节点的前驱节点的waitStatus设置为SIGNAL(意思就是当前节点需要进入阻塞状态,
            // 当然这里只是先将当前节点的前驱节点的waitStatus设置为SIGNAL,
            // 下一轮自旋才能将当前节点设置为阻塞状态)
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;
    }
posted @ 2020-03-17 15:25  04300115116  阅读(162)  评论(0编辑  收藏  举报