美文网首页
ReentrantLock

ReentrantLock

作者: Pillar_Zhong | 来源:发表于2019-06-05 16:18 被阅读0次
ReentrantLock.png

FairSync

lock

final void lock() {
    // 可以跟非公平锁做对比,这里会去调用acquire来通过公平原则来加锁
    acquire(1);
}

tryAcquire

protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    // 等于0,说明锁还没有被其他线程持有
    if (c == 0) {
        // 当hasQueuedPredecessors为false的情况才会去拿锁,也就是队列中第一个等待的当前线程
        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;
}
public final boolean hasQueuedPredecessors() {
    // The correctness of this depends on head being initialized
    // before tail and on head.next being accurate if the current
    // thread is first in queue.
    Node t = tail; // Read fields in reverse initialization order
    Node h = head;
    Node s;
    // 而这里返回false的情况也就两种
    // 1. head=tail,说明队列还没有waiter
    // 2. 队列中有waiter,且当前线程是第一个
    return h != t &&
        ((s = h.next) == null || s.thread != Thread.currentThread());
}

NonfairSync

lock

final void lock() {
    // 非公平锁的意义在于,谁先来,谁抢锁。所以,这里一上来直接试着抢锁,如果能抢到,最好不过了。
    // 直接设置为当前线程
    // 如果没抢到,那没办法,走非公平锁的正常流程
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1);
}

tryAcquire

protected final boolean tryAcquire(int acquires) {
    return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    // 等于0,说明锁还没有被其他线程持有
    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;
}

tryRelease

protected final boolean tryRelease(int releases) {
    // 重入计数自减
    int c = getState() - releases;
    // 如果持有人不是当前线程,当然也就没有资格释放锁,报异常
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    // 如果重入计数归零,说明该锁已经完成释放,清理现场
    if (c == 0) {
        free = true;
        setExclusiveOwnerThread(null);
    }
    // 更新state
    setState(c);
    return free;
}

相关文章

网友评论

      本文标题:ReentrantLock

      本文链接:https://www.haomeiwen.com/subject/qjhsxctx.html