Java 不可重入锁和可重入锁理解
Java 不可重入锁和可重入锁理解
基础知识
Java 多线程的 wait() 方法和 notify() 方法
这两个方法是成对出现和使用的,要执行这两个方法,有一个前提就是,当前线程必须获其对象的 monitor(俗称 “锁”),否则会抛出 IllegalMonitorStateException 异常,所以这两个方法必须在同步块代码里面调用。
wait():阻塞当前线程
notify():唤起被 wait() 阻塞的线程
不可重入锁
所谓不可重入锁,即若当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞。我们尝试设计一个不可重入锁:

使用该锁:

当前线程执行 print() 方法首先获取 lock,接下来执行 doAdd() 方法就无法执行 doAdd() 中的逻辑,必须先释放锁。这个例子很好的说明了不可重入锁。
所谓可重入,意味着线程可以进入它已经拥有的锁的同步代码块儿。
我们设计两个线程调用 print() 方法,第一个线程调用 print() 方法获取锁,进入 lock() 方法,由于初始 lockedBy 是 null,所以不会进入 while 而挂起当前线程,而是是增量 lockedCount 并记录 lockBy 为第一个线程。接着第一个线程进入 doAdd() 方法,由于同一进程,所以不会进入 while 而挂起,接着增量 lockedCount,当第二个线程尝试 lock,由于 isLocked=true, 所以他不会获取该锁,直到第一个线程调用两次 unlock() 将 lockCount 递减为 0,才将标记为 isLocked 设置为 false。
可重入锁的概念和设计思想大体如此,Java 中的可重入锁 ReentrantLock 设计思路也是这样

浙公网安备 33010602011771号