AQS execution process analysis

AbstractQueuedSynchronizer (abstract queue-style synchronizer)

Function

data structure

Node

static final class Node {
    /** 指示节点正在共享模式下等待的标记 */
    static final Node SHARED = new Node();
    /** 指示节点正在以独占模式等待的标记 */
    static final Node EXCLUSIVE = null;

    /** waitStatus值,指示线程已取消 */
    static final int CANCELLED =  1;
    /** waitStatus值,指示后续线程需要取消停放 */
    static final int SIGNAL    = -1;
    /** waitStatus值,指示线程正在等待条件 */
    static final int CONDITION = -2;
    /** waitStatus值,指示下一个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, 添加到等待队列 */
    Node(Thread thread, Node mode) {     
        this.nextWaiter = mode;
        this.thread = thread;
    }

    /** 会在condition队列中使用 */
    Node(Thread thread, int waitStatus) { // Used by Condition
        this.waitStatus = waitStatus;
        this.thread = thread;
    }
}

Sync

FairSync

NonfairSync

Execution flow (NonfairSync in ReentrantLock)

  1. The thread tries to acquire the lock and compareAndSetStatesets the cas through the method. If the lock is successfully acquired, the current thread is written into the exclusiveOwnerThreadvariable. If the thread fails to acquire the lock, it will be acquireacquired in the exclusive mode through the method.

    final void lock() {
        // 通过cas设置状态,设置成功说明获取锁
        if (compareAndSetState(0, 1))
            // 设置锁拥有者为当前线程
            setExclusiveOwnerThread(Thread.currentThread());
        else
            // 在独占模式下获取,忽略中断
            acquire(1);
    }
    
  2. Call tryAcquire-> nonfairTryAcquire, which performs an unfair way of acquiring the lock

    1. Call tryAcquire-> nonfairTryAcquire, first determine whether the lock is released, try to acquire the lock in a lock-free state
    2. If the current thread and the thread holding the lock are the same, the lock is reentrant, and the lock state is +1
    // 尝试获取锁
    public final void acquire(int arg) {
        // tryAcquire 尝试获取锁
        // acquireQueued 添加到阻塞队列
        // addWaiter 创建并排队当前线程和给定模式的节点
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
    // tryAcquire
    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
    /**
     * 执行不公平的tryLock。 tryAcquire是在子类中实现的,但是都需要对trylock方法进行不公平的尝试
     */
    final boolean nonfairTryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        // 获取AQS的队列,如果是无锁状态进行尝试获取锁, 与
        if (c == 0) {
            if (compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(current);
                return true;
            }
        }
    	// 重入锁处理 如果是已经拥有锁的线程,对状态+1
        else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            if (nextc < 0) // overflow
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        // 获取锁失败
        return false;
    }
    
  3. After a failed attempt to acquire a lock, add to the blocking queue for queuing

  4. call addWaitercreate

// 尝试获取锁
public final void acquire(int arg) {
    // tryAcquire 尝试获取锁
    // acquireQueued 添加到阻塞队列
    // addWaiter 创建并排队当前线程和给定模式的节点
    if (!tryAcquire(arg) &&
        // Node.EXCLUSIVE
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}
// 添加到等待队列中
private Node addWaiter(Node mode) {
    // 将当前线程包装成Node节点
    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)) {
            pred.next = node;
            return node;
        }
    }
    // 插入队列
    enq(node);
    return node;
}
// 将节点插入队列,必要时进行初始化
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;
            // 通过cas设置当前节点为尾节点
            if (compareAndSetTail(t, node)) {
                // 设置成功将之前尾节点的下一节点设置为当前节点
                t.next = node;
                return t;
            }
            // cas设置失败说明尾节点发生了变更,需要自旋继续尝试设置
        }
    }
}
// 添加到阻塞队列
final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            if (p == head && tryAcquire(arg)) {
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted;
            }
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324215604&siteId=291194637