某友面试的几个问题,当时确实难到我了,为了节省篇幅,我把我未能回答出来的问题写出来,未回答出的问题只有一个。
为什么要可重入锁,什么情况下会重入锁?
重复进入一个锁,当时我的回答是粗心的程序员会重入一个锁。这个答案肯定是错误的。我们首先要审题,审题突出审字,就是要仔细分析题。这里说的重入锁,没有说是Java的多线程锁,而是一个通用的锁概念。锁分很多种,数据库锁、文件锁、多线程锁,分布式锁等等。这个锁的分类标准是什么?是锁需要保护的资源,资源可以分为数据库数据、磁盘文件、执行的代码块、分布式的服务。
那首先可以回答第一个问题,这个比较简单。但是如果这样回答“让同一个访问者反复访问被保护的资源,所以需要重入锁”肯定是不严谨的。因为没有区分重入与不可重入。重入真正含义是已经上锁了,还能进入,这才是重入。所以正确的回答是:
某些场景下,需要在锁未释放时,锁的拥有者能重新访问被保护的资源,所以需要可重入锁。
那什么情况下会重入呢?
第一种情况,程序员粗心大意,比如以下java代码:
public class TestThread {
private static TestThread lock = new TestThread();
public static void main(String[] args) {
synchronized (lock) {
synchronized (lock) {
System.out.println("x");
}
}
}
}
但是得有多脑残才能写出这种代码。所以这种情况会出现,但是可能性很小。
再想想别的情况,比如循环呢?循环肯定不是,循环是上锁-解锁-再上锁-再解锁的过程,所以不会出现重入锁的情况。那么在未释放锁之前重新获取锁只剩下一种情况了,就是递归,递归是方法未返回再重新调用方法。因为锁的进入和退出,归根结底都是某个函数/方法/过程去执行的。顺便提一句,可重入锁也叫递归锁。