重入锁死

欢马劈雪     最近更新时间:2020-08-04 05:37:59

176

重入锁死与死锁嵌套管程锁死非常相似。读写锁两篇文章中都有涉及到重入锁死的问题。

当一个线程重新获取锁,读写锁或其他不可重入的同步器时,就可能发生重入锁死。可重入的意思是线程可以重复获得它已经持有的锁。Java 的 synchronized 块是可重入的。因此下面的代码是没问题的:

(译者注:这里提到的锁都是指的不可重入的锁实现,并不是 Java 类库中的 Lock 与 ReadWriteLock 类)

public class Reentrant{
    public synchronized outer(){
        inner();
    }

    public synchronized inner(){
        //do something
    }
}

注意 outer()和 inner()都声明为 synchronized,这在 Java 中这相当于 synchronized(this)块(译者注:这里两个方法是实例方法,synchronized 的实例方法相当于在 this 上加锁,如果是 static 方法,则不然,更多阅读:哪个对象才是锁?)。如果某个线程调用了 outer(),outer()中的 inner()调用是没问题的,因为两个方法都是在同一个管程对象(即 this)上同步的。如果一个线程持有某个管程对象上的锁,那么它就有权访问所有在该管程对象上同步的块。这就叫可重入。若线程已经持有锁,那么它就可以重复访问所有使用该锁的代码块。

下面这个锁的实现是不可重入的:

public class Lock{
    private boolean isLocked = false;
    public synchronized void lock()
        throws InterruptedException{
        while(isLocked){
            wait();
        }
        isLocked = true;
    }

    public synchronized void unlock(){
        isLocked = false;
        notify();
    }
}
展开阅读全文