可重入锁与非可重入锁

@[toc]

锁的分类

在这里插入图片描述

什么是可重入锁

可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提锁对象得是同一个对象或者class),不会因为之前已经获取过还没释放而阻塞。Java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可一定程度避免死锁。

  • ReentrantLock和synchronized都是重入锁,

  • 可重入锁的好处:【1.避免死锁】【2.提升封装性】

案例实现
  • 电影院预定预定电影院座位

预定座位就是个很好的lock锁场景,预定座位,其实这个背后就是上锁了 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

首先ReentrantLock和NonReentrantLock都继承父类AQS,其父类AQS中维护了一个同步状态status来计数重入次数,status初始值为0。 当线程尝试获取锁时,可重入锁先尝试获取并更新status值,如果status == 0表示没有其他线程在执行同步代码,则把status置为1,当前线程开始执行。如果status != 0,则判断当前线程是否是获取到这个锁的线程,如果是的话执行status+1,且当前线程可以再次获取锁。而非可重入锁是直接去获取并尝试更新当前status的值,如果status != 0的话会导致其获取锁失败,当前线程阻塞。 释放锁时,可重入锁同样先获取当前status的值,在当前线程是持有锁的线程的前提下。如果status-1 == 0,则表示当前线程所有重复获取锁的操作都已经执行完毕,然后该线程才会真正释放锁。而非可重入锁则是在确定当前线程是持有锁的线程之后,直接将status置为0,将锁释放。

测试lock 锁的可重入性

在这里插入图片描述

我们使用 lock.getHoldCount() 打印下获取锁的次数 多次获取锁,与释放锁 在这里插入图片描述 会发现锁不用等待,下一次依然可以获取到锁,这就是锁的可重入锁性

不可重入锁

不可重入锁,与可重入锁相反,不可递归调用,递归调用就会发生死锁。

end
  • 作者:yxl(联系作者)
  • 发表时间:2020-08-11 15:41
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 公众号转载:请在文末添加作者公众号二维码(公众号二维码见右边,欢迎关注)
  • 评论