转载

探索JAVA并发 - 可重入锁和不可重入锁

什么是可重入锁,什么是不可重入锁,它们是如何实现的?

定义

  • 可重入锁:当线程获取某个锁后,还可以继续获取它,可以递归调用,而不会发生死锁;

  • 不可重入锁:与可重入相反,获取锁后不能重复获取,否则会死锁(自己锁自己)。

不可重入锁

用代码说话。

基于 wait/notify 实现不可重入锁

第二次调用lock后线程就阻塞了,线程开始等待持有锁的线程放手,然而是它是它就是它。

基于自旋锁实现不可重入锁

自旋锁,即获取锁的线程在锁被占用时,不是阻塞,而是不断循环去尝试,直到获取锁。

  • 好处:线程保持活跃,减少了线程切换的开销

  • 缺点:很消耗CPU,特别是等待时间很长时

如果不想磁盘爆掉,不要在自旋过程中随便打印日志:smiling_imp:

可重入锁

不可重入锁扩展一下,增加一个计数器,同一个线程每次获取锁计数器加1,释放锁减1,为0时释放锁。

基于自旋锁实现可重入锁

直接用上个例子的代码改一下:

可重入锁 synchronized

没错,用于声明同步方法/代码块的synchronized关键字提供的也是一个可重入锁。

同步方法递归测试:

可重入锁 ReentrantLock

ReentrantLock是Java中很常见的工具类, 从名字就可以看出,它是个可重入锁,用法也很简单:

更多内容,欢迎关注微信公众号: 全菜工程师小辉 。后台回复关键词领取免费学习资料。

探索JAVA并发 - 可重入锁和不可重入锁

原文  http://mp.weixin.qq.com/s?__biz=MzUyNzgyNzAwNg==&mid=2247484045&idx=1&sn=a0f837a18e9dd4cbd6772d97c701e733
正文到此结束
Loading...