java

JUC.ReentrantLock

2019-06-03  本文已影响0人  小明17

ReentrantLock是JDK提供的一个可重入互斥锁,所谓可重入就是同一个锁允许被已经获得该锁的线程重新获得。可重入锁的好处可以在递归算法中使用锁,不可重入锁则导致无法在递归算法中使用锁。因为第二次递归时由于第一次递归已经占有锁,而导致死锁。

1.默认构造函数是new一个非公平锁

public ReentrantLock() {
        sync = new NonfairSync();
}

2.因为是独占式锁,需要实现AQS的tryAcquire函数和tryRelease函数

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;
}
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);
        }
        setState(c);
        return free;
}

3.ReentrantLock的两个主要方法lock和unlock源码了解一下:

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

该函数首先直接尝试CAS操作,成功则设置当前函数为占有锁的函数,返回,失败则调用acquire函数。acquire函数为AQS实现的模板方法,它尝试获得锁,成功则返回,不成功则进入等待队列直至获取成功。

public void unlock() {
    sync.release(1);
}
public final boolean release(int arg) {
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            unparkSuccessor(h);
        return true;
    }
    return false;
}

调用tryRelease函数释放锁

上一篇 下一篇

猜你喜欢

热点阅读