分析下ReentrantLock调用lock的fairSync版本

reentrantLock调用lock的fairSync版本

1 reentrantLock调用lock

public void lock() {
    sync.lock();    -> 2 :调用sync的lock方法,选的fairsync作为例子
}

2 调用acquire方法,尝试获取锁

final void lock() {
        acquire(1);   -> 3
  }

3 (1)获取锁成功,退出. (2)获取锁失败,添加node至队列尾部

	 public final void acquire(int arg) {
  	 if (!tryAcquire(arg) &&   -->4
      acquireQueued(addWaiter(Node.EXCLUSIVE), arg))      ---->6.(5) 
      selfInterrupt();
	}

4 原子地获取锁,(1)获取成功则将state由0添加至1.(2) 重入则添加state计数器,(3)否则失败

     protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
            if (!hasQueuedPredecessors() &&
                compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            if (nextc < 0)
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }

5 将信息为当前线程的Node原子性地添加至队列尾部.(1).尾部不为空则cas操作尾部引用设置为当前node.并且将之前的尾部的next设置为当前node. (2)尾部为空则设置头尾为一个新的Node,然后设置当前node为尾,然后将当前node设置为尾

    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)) {
            pred.next = node;
            return node;
        }
    }
    enq(node);
    return node;
}

6 如果node的前节点为head,如果获取锁权限成功,则将头节点设置为当前节点,并且释放前节点,返回interrupted状态(设置interupted用)
如果前节点不为head或者获取锁权限失败, 则根据前驱节点的waitStatus如果为signal则阻塞当前线程,如果不为signal则设置为signal继续循环
循环

    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) &&       ---->7
                parkAndCheckInterrupt())									---->8
                interrupted = true;
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

7 前驱节点为signl则直接安全的返回true… return
如果前驱节点为cancel,则全部取消直到不需要取消的节点,然后将节点的后继者设置为当前节点. return false
否则cas原子性地将前节点地statu设置为signal return false

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
    int ws = pred.waitStatus;
    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.
         */
        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.
         */
        compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
    }
    return false;
}

8 locksupport 将当前线程的blocker设置为当前locksupport .阻塞当前线程. 醒了就设置为空.传递interupted状态

private final boolean parkAndCheckInterrupt() {
    LockSupport.park(this);
    return Thread.interrupted();
}
public static void park(Object blocker) {
    Thread t = Thread.currentThread();
    setBlocker(t, blocker);
    UNSAFE.park(false, 0L);
    setBlocker(t, null);
}
private static void setBlocker(Thread t, Object arg) {
    // Even though volatile, hotspot doesn't need a write barrier here.
    UNSAFE.putObject(t, parkBlockerOffset, arg);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章