ReentrantLock源码阅读

默认构造方法初始化同步器为非公平同步器

    /**
     * Creates an instance of {@code ReentrantLock}.
     * This is equivalent to using {@code ReentrantLock(false)}.
     */
    public ReentrantLock() {
        sync = new NonfairSync();
    }

 lock()方法调用的是sync的lock()方法

    public void lock() {
        sync.lock();
    }

    final void lock() {
        if (compareAndSetState(0, 1))
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);
    }

如果将state从0改为1成功,那么将属性exclusiveOwnerThread改为当前线程,代表获得锁成功

    protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }
    
    protected final void setExclusiveOwnerThread(Thread thread) {
        exclusiveOwnerThread = thread;
    }

修改失败走acquire,参数arg为1

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

三步走

1.tryAcquire调用的是nonfairTryAcquire

protected final boolean tryAcquire(int acquires) {
    return nonfairTryAcquire(acquires);
}

//aquire为1
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState();
  //这个逻辑什么时候会走?其他线程第一次抢锁失败,然后恰好获得锁的线程释放了锁?
if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } }
  //获得锁的线程重入会走这个逻辑
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; }

2.又一次抢锁失败,且不是当前线程重入,tryAcquire返回false,走下一步逻辑acquireQueued(addWaiter(Node.EXCLUSIVE), arg))

2.1 addWaiter(Node.EXCLUSIVE)  (将新节点插入尾节点之后,如果尾节点为空,初始化一个新节点,没有线程,既是头也是尾,返回新节点有thread没有addwaiter)

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;
}

Node(Thread thread, Node mode) {     // Used by addWaiter
    this.nextWaiter = mode;
    this.thread = thread;
}

private Node enq(final Node node) {
    for (;;) {
        Node t = tail;
        //尾节点为空,初始化一个新节点,头和尾都指向他
        if (t == null) { // Must initialize
            if (compareAndSetHead(new Node()))
                tail = head;
        } else {
        //将node节点放入尾节点之后,一次次直到成功
            node.prev = t;
            if (compareAndSetTail(t, node)) {
                t.next = node;
                return t;
            }
        }
    }
}

Node() {    // Used to establish initial head or SHARED marker
}

2.2 acquireQueued

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; }
       //将当前节点的前一个结点的waitStatus改为-1(循环直到成功),挂起当前节点lockSupport.park
if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } }
原文地址:https://www.cnblogs.com/scorates/p/14603427.html