19 ReentrantLock如何实现锁重入
2022-11-08 本文已影响0人
滔滔逐浪
一个线程持有锁时,当其他的线程尝试获取该锁时,会被阻塞;而这个线程尝试获取自己持有锁时,如果成功说明锁是可以重入的,反之则不可重入。
ReentrantLock使用内部类的Sync来管理锁,所以真正的获取锁是由Sync的实现类来控制的。Sync又有2个实现,分别为NonfairSync(非公平锁)和FairSync(公平锁)。Sync通过继承AQS实现,在AQS中维护了一个private volatile in state 来计算重入次数,避免频繁的持有释放操作带来的线程问题。
synchronized 关键字经过编译后,会在同步快的前后分别形成monitorenter和monitoreit2个字节码指令。每个锁对象内部维护一个计时器,该计时器初始值为0,表示任何线程都可以获取该锁并执行相应的方法。根据虚拟规范要求,在执行minitorenter指令时,首先尝试获取对象的锁,如果这个对象没有被锁定,或者当前线程已经拥有了对象的锁,把锁的计数器+1,相应的在执行monitorexit指令后锁计数器-1,当计数器为0时,锁就被释放,如果获取对象锁失败,那当前线程就要阻塞等待,直到对象锁被另一个线程释放为止。