可重入锁(ReentrantLock为例)

2年前 (2022) 程序员胖胖胖虎阿
274 0 0

什么是可重入锁

        STFW得到以下两种主流解释

        解释一:可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。

        解释二:可重入锁又称递归锁,是指同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是锁对象得是同一个对象),不会因为之前已经获取过锁还没有释放而阻塞。

疑惑

        解释一中提到了可以再次获取锁,“再次获取锁”是如何进行判断的呢?

        解释二中提到了可重入锁称为递归锁,因此就想当然的理解为可重入锁是某段代码方法中,一个锁里面嵌套着某个锁。那么难道锁不进行嵌套就不是可重入锁了吗?

        解释一和解释二总感觉描述的不是一个东西。

证明

        首先,我们已知ReentrantLock是可重入锁,那么它的可重入是怎么实现的呢,源码中有这样一段代码。

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

        if (current == getExclusiveOwnerThread())这一段就是进行可重入锁的判断,因此可以得知,可重入锁就是在加锁时判断当前线程是否是已经获取到锁的线程,如果是的话,锁的次数会+1。需要注意的是既然多次加锁,就需要多次释放锁。

解释

        解释一:可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。

        这是可重入锁的概念描述。

        解释二:可重入锁又称递归锁,是指同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是锁对象得是同一个对象),不会因为之前已经获取过锁还没有释放而阻塞。

        这是可重入锁的一种表现方式,不代表说某段代码中的锁没有发生嵌套,这个锁就不是可重入锁。

总结

        可重入锁是某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。再次获取锁的时候会判断当前线程是否是已经加锁的线程,如果是对锁的次数+1,释放锁的时候加了几次锁,就需要释放几次锁。

        代码中的锁的递归只是锁的一种表现及证明形式,除了这种形式外,还有另一种表现形式。同一个线程在没有释放锁的情况下多次调用一个加锁方法,如果成功,则也说明是可重入锁。

版权声明:程序员胖胖胖虎阿 发表于 2022年10月28日 上午2:56。
转载请注明:可重入锁(ReentrantLock为例) | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...