应用样例

ThreadA、ThreadB、ThreadC拜访如下逻辑ReentrantLock lock = new ReentrantLock();// == 1.加锁lock.lock();...省略业务解决...// == 2.开释lock.unlock();

非偏心加锁过程

偏心形式,无ThreadD局部逻辑,会间接入队

后续都在具体解释这张图

一、非偏心加锁

1.状态批改

// ## 状态:拜访线程会采纳cas的形式批改state的值,加锁过程0->1private volatile int state;// ## 持有线程:state批改胜利的线程,将被记录。比方,exclusiveOwnerThread=ThreadAprivate transient Thread exclusiveOwnerThread;# NonfairSync 非偏心实现final void lock() {    // == 1.cas 批改state状态 0->1(插队1)    if (compareAndSetState(0, 1))        // state批改胜利批改持有线程 exclusiveOwnerThread = ThreadA        setExclusiveOwnerThread(Thread.currentThread());    else        // == 2.构建队列,并阻塞线程        acquire(1);}

2.队列构建

### public final void acquire(int arg) {    // a-尝试获取,尝试批改state状态(未获取胜利持续后续逻辑)    if (!tryAcquire(arg)             // b2-排队获取            && acquireQueued(                // b1-新增期待节点,构建“独占”模式队列                addWaiter(Node.EXCLUSIVE), arg))                        selfInterrupt();}

a-尝试获取(可能插队的地位)

java.util.concurrent.locks.ReentrantLock.NonfairSync#tryAcquirejava.util.concurrent.locks.ReentrantLock.Sync#nonfairTryAcquirefinal boolean nonfairTryAcquire(int acquires) {    final Thread current = Thread.currentThread();    int c = getState();    // ## 插队地位    if (c == 0) {        if (compareAndSetState(0, acquires)) {            setExclusiveOwnerThread(current);            return true;        }    }    // ## 重入,state++    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;}

b1-新增期待节点,构建“独占”模式队列

class Node {    /** 独占 */    static final Node EXCLUSIVE = null;    // 指向线程    volatile Thread thread;    volatile Node prev;    volatile Node next;       static final int SIGNAL    = -1;
java.util.concurrent.locks.AbstractQueuedSynchronizer#addWaiterprivate 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;    // == 2.队列不为空,节点尾插    if (pred != null) {        node.prev = pred;        if (compareAndSetTail(pred, node)) {            pred.next = node;            return node;        }    }    // == 1.队列初始构建    enq(node);    return node; // 返回尾节点}//== 1.队列初始构建java.util.concurrent.locks.AbstractQueuedSynchronizer#enqprivate Node enq(final Node node) {    for (;;) {        Node t = tail;        // -- A、初始化构建,头尾指针指向空Node        if (t == null) {             if (compareAndSetHead(new Node()))                tail = head;        }         // -- B、尾插        else {            node.prev = t;            // cas 批改尾节点指向            if (compareAndSetTail(t, node)) {                t.next = node;                return t; // 返回头节点            }        }    }}

b2-排队获取

java.util.concurrent.locks.AbstractQueuedSynchronizer#acquireQueuedfinal boolean acquireQueued(final Node node, int arg) {    boolean failed = true;    try {        boolean interrupted = false;        // 循环中        for (;;) {            final Node p = node.predecessor();            // ### 前置节点是头节点,有机会尝试获取            //(联合下一个if判断,会自旋两次,也就是说有两次尝试获取机会)            if (p == head && tryAcquire(arg)) {                setHead(node);                p.next = null; // help GC                failed = false;                return interrupted;            }            // ### 第1次将waitstatus设置成signal返回false             // ###    第2次判断waitstatus==signal返回true            if (shouldParkAfterFailedAcquire(p, node)                     // === 线程阻塞(将来唤醒时,从此处继续执行)                    && parkAndCheckInterrupt())                interrupted = true;        }    } finally {        if (failed)            cancelAcquire(node);    }}###private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {    int ws = pred.waitStatus;    // -- 第二次调用    if (ws == Node.SIGNAL)        return true;        if (ws > 0) {        do {            node.prev = pred = pred.prev;        } while (pred.waitStatus > 0);        pred.next = node;    }     // -- 第一次调用    else {        compareAndSetWaitStatus(pred, ws, Node.SIGNAL);    }    return false;}===private final boolean parkAndCheckInterrupt() {    LockSupport.park(this);    // 以后线程是否被中断    return Thread.interrupted();}

二、开释

java.util.concurrent.locks.ReentrantLock#unlockjava.util.concurrent.locks.AbstractQueuedSynchronizer#release{    // == 1.state还原,exclusiveOwnerThread清空    if (tryRelease(arg)) {        Node h = head;        if (h != null && h.waitStatus != 0)            // == 2.“解除阻塞”执行胜利的节点            unparkSuccessor(h);        return true;    }    return false;}

1.state还原,exclusiveOwnerThread清空

protected final boolean tryRelease(int releases) {    // 加锁时线程重入,state++。因而解锁时,state--    int c = getState() - releases;    if (Thread.currentThread() != getExclusiveOwnerThread())        throw new IllegalMonitorStateException();    boolean free = false;    // state归0时,开释线程援用    if (c == 0) {        free = true;        setExclusiveOwnerThread(null);    }    setState(c);    return free;}

2.“解除阻塞”执行胜利的节点

private void unparkSuccessor(Node node) {    int ws = node.waitStatus;    // 加锁时,ws=SIGNAL,也就是-1。当初改成0    if (ws < 0)        compareAndSetWaitStatus(node, ws, 0);    /*     * Thread to unpark is held in successor, which is normally     * just the next node.  But if cancelled or apparently null,     * traverse backwards from tail to find the actual     * non-cancelled successor.     */    Node s = node.next;    if (s == null || s.waitStatus > 0) {        s = null;        for (Node t = tail; t != null && t != node; t = t.prev)            if (t.waitStatus <= 0)                s = t;    }    // ## 开释s节点,也就是head的下一个节点    if (s != null)        LockSupport.unpark(s.thread);}

三、偏心加锁

差异一

# FairSync 偏心实现final void lock() {    // 无插队操作,间接构建队列    acquire(1);}

再比照下刚刚的非偏心实现,只有else局部

# NonfairSync 非偏心实现final void lock() {    // == 1.cas 批改state状态 0->1(插队1)    if (compareAndSetState(0, 1))        // state批改胜利批改持有线程 exclusiveOwnerThread = ThreadA        setExclusiveOwnerThread(Thread.currentThread());            ### 偏心实现只有这部分逻辑      else        // == 2.构建队列,并阻塞线程        acquire(1);}

差异二

public final void acquire(int arg) {    if (!tryAcquire(arg)             && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))        selfInterrupt();}protected final boolean tryAcquire(int acquires) {        final Thread current = Thread.currentThread();        int c = getState();        if (c == 0) {            // ### 偏心实现(多了!hasQueuedPredecessors()):要求无排队状况才有资格尝试进行后续cas操作            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;    }}