重入锁定
时间:2020-01-09 10:35:52 来源:igfitidea点击:
重入锁定是一种类似于死锁和嵌套监视器锁定的情况。重入锁定也包含在"锁定"和"读/写锁定"中。
如果线程重新输入Lock,ReadWriteLock或者其他不可重入的同步器,则可能会发生重入锁定。可重入意味着已持有锁的线程可以重新获取它。 Java的同步块是可重入的。因此,以下代码可以正常工作:
public class Reentrant{ public synchronized outer(){ inner(); } public synchronized inner(){ //do something } }
注意,如何将" outer()"和" inner()"都声明为已同步,这在Java中等效于" synchronized(this)"块。如果线程调用outer()
,则从outer()
内部调用inner()是没有问题的,因为两个方法(或者块)都在同一个监视对象(" this")上同步。如果线程已经拥有监视对象上的锁,则它可以访问在同一监视对象上同步的所有块。这称为重入。线程可以重新输入已经为其持有锁的任何代码块。
以下Lock
实现不是可重入的:
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(); } }
如果一个线程两次调用了" lock()"而没有在其间调用" unlock()",则对" lock()"的第二次调用将被阻塞。重新进入锁定已发生。
为了避免重新进入锁定,我们有两种选择:
- 避免编写重新输入锁定的代码
- 使用可重入锁
以下哪种选项最适合项目,取决于具体情况。可重入锁的性能通常不如不可重入锁,并且很难实现,但这在情况下可能不是问题。无论有没有锁再入,代码是否易于实现都必须视情况而定。