✅什么是可重入锁,怎么实现可重入锁?

典型回答

可重入锁是一种多线程同步机制,允许同一线程多次获取同一个锁而不会导致死锁。这意味着一个线程可以在持有锁的情况下再次请求并获得相同的锁,而不会被自己阻塞。可重入锁有助于避免死锁和提高代码的可维护性,因为它允许在一个线程中嵌套地调用锁定的方法。

如我们常用的synchronized和reentrantLock都是比较典型的可重入锁。也就是说,在一个线程调用synchronized方法的同时,可以在其方法体内部调用该对象另一个synchronized方法,也就是说一个线程得到一个对象锁后再次请求该对象锁。

public class ReentrantLockTest {

    public static void main(String[] args) {
        ReentrantLockTest reentrantLockTest = new ReentrantLockTest();
        reentrantLockTest.method1();
    }

    public synchronized void method1(){
        method2();
        System.out.println("invoke method1");
    }

    public synchronized void method2() {
        System.out.println("invoke method2");
    }
}

如以上代码,即可输出:

invoke method2
invoke method1

在可重入锁的实现上,一般是先要记录下来当前锁是归属于哪个线程的,然后再记录当前锁被重入了多少次。这样在加锁的时候判断是不是当前线程持有的锁,如果是则重入次数+1,否则重入失败。

在解锁时也同理,锁是当前线程加的,那就重入次数-1,直到等于0的时候,直接解锁。

以下就是reentrantLock的加锁代码:

if (current == getExclusiveOwnerThread()) {
     int nextc = c + acquires;
     if (nextc < 0)
        throw new Error("Maximum lock count exceeded");
     setState(nextc);
     return true;
 }

以下就是reentrantLock的解锁代码:

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

原文: https://www.yuque.com/hollis666/xkm7k3/zvx2w5h9sr7trle7