转自:https://www.jianshu.com/p/6e8a49121133
1.概念
可重入 就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。锁的操作粒度是”线程”,而不是调用,同一个线程再次进入同步代码的时候.可以使用自己已经获取到的锁,这就是可重入锁。
2.例子
可重入锁也叫递归锁,是指对同一线程而言的。
public class Widget { public synchronized void doSomething() { ... } } public class LoggingWidget extends Widget { public synchronized void doSomething() { System.out.println(toString() + ": calling doSomething"); super.doSomething();//若内置锁是不可重入的,则发生死锁 } }
子类中要调用父类的方法,再获取一次锁,子类的doSomething方法当前已经获取了,如果调用父类的方法还要再次获取锁,那么就会出现死锁,等待自己释放锁。
可重入锁主要用在线程需要多次进入临界区代码时,需要使用可重入锁。
3.实现原理
为每个锁关联一个获取计数器和一个所有者线程,当计数值为0的时候,这个锁就没有被任何线程持有。
- 加锁时,需要判断锁是否已经被获取。如果已经被获取,则判断获取锁的线程是否是当前线程。如果是当前线程,则给获取次数加1。如果不是当前线程,则需要等待。
- 释放锁时,需要给锁的获取次数减1,然后判断,次数是否为0了。如果次数为0了,则需要调用锁的唤醒方法,让锁上阻塞的其他线程得到执行的机会。