欢迎来到《并发王者课》,本文是该系列文章中的第16篇

在前面的文章《铂金1:探本溯源-为何说Lock接口是Java中锁的基础》中,我们提到了锁的可重入问题,并作了简单介绍。鉴于锁的可重入是一个重要概念,所以本文把拿出来做一次单独讲解,以帮助你彻底理解它。

一、锁的可重入所造成的问题

首先,我们通过一段示例代码看锁的可重入是如何导致问题发生,以理解它的重要性。

public class ReentrantWildArea {// 野区锁定private boolean isAreaLocked = false;// 进入野区Apublic synchronized void enterAreaA() throws InterruptedException {isAreaLocked = true;System.out.println("已经进入野区A...");enterAreaB();}// 进入野区Bpublic synchronized void enterAreaB() throws InterruptedException {while (isAreaLocked) {System.out.println("野区B方法进入等待中...");wait();}System.out.println("已经进入野区B...");}public synchronized void unlock() {isAreaLocked = false;notify();}
}

在上面这段代码中,我们创建了一片野区,包含了野区A野区B。接着,我们再创建一个打野英雄铠,让他进去野区打野,看看会发生什么事情。

public static void main(String[] args) {// 打野英雄铠进入野区Thread kaiThread = new Thread(() -> {ReentrantWildArea wildArea = new ReentrantWildArea();try {wildArea.enterAreaA();} catch (InterruptedException e) {e.printStackTrace();}});kaiThread.start();
}

输出结果如下:

已经进入野区A...
野区B方法进入等待中...

从结果中可以看到,虽然在同一块野区,但是铠只进入野区A,却没能进入野区B,被阻塞在半道上了。从代码分析上看,野区的两个方法都声明了synchronized,但铠在进入野区A之后,野区进行了锁定isAreaLocked = true,导致铠进入野区B时失败。

这就是典型的锁的可重入所造成的问题。在并发编程时,如果未能处理好这一问题,将会造成线程的无限阻塞,其后果和死锁相当

二、理解锁的可重入

所谓锁的可重入,指的是锁可以被线程 重复递归 调用,也可以理解为对同一把锁的重复获取。 如果未能处理好锁的可重入问题,将会导致和死锁类似的问题。

三、如何避免锁的可重入问题

避免锁的可重入问题,需要注意两个方面:

  • 尽量避免编写需要重入获取锁的代码
  • 如果需要,使用可重入锁

在Java中,synchronized是可以重入的,下面的这段代码在调用时不会产生重入问题。

public class WildMonster {public synchronized void A() {B();}public synchronized void B() {doSomething...}
}

但是,基于Lock接口所实现的各种锁并不总是支持可重入的。在前面的文章中,我们已经展示过不支持重入的Lock接口实现。在具体的场景中使用时,需要务必注意这点。如果需要可重入锁,可以使用Java中的ReentrantLock类。

小结

在本文中,我们再次介绍了锁的可重入问题,并介绍了其产生的原因及避免方式。Java中的synchronized关键字支持锁的可重入,但是其他显示锁并非总是支持这一特性,在使用时需要注意。

此外,需要注意的是,锁的可重入对锁的性能有一定的影响,而且实现起来更为复杂。所以,我们不能说锁的可重入与不可重入哪个好,这要取决于具体的问题

正文到此结束,恭喜你又上了一颗星✨

夫子的试炼

  • 查看ReentrantLock源码,了解其支持可重入的原理。

延伸阅读与参考资料

  • 《并发王者课》大纲与更新进度总览

关于作者

关注公众号【技术八点半】,及时获取文章更新。传递有品质的技术文章,记录平凡人的成长故事,偶尔也聊聊生活和理想。早晨8:30推送作者品质原创,晚上20:30推送行业深度好文。

如果本文对你有帮助,欢迎点赞关注监督,我们一起从青铜到王者

铂金03:一劳永逸-如何理解锁的可重入问题相关推荐

  1. 并发王者课-铂金3:一劳永逸-如何理解锁的多次可重入问题

    欢迎来到<并发王者课>,本文是该系列文章中的第16篇. 在前面的文章<铂金1:探本溯源-为何说Lock接口是Java中锁的基础>中,我们提到了锁的可重入问题,并作了简单介绍.鉴 ...

  2. 王者并发课-铂金3:一劳永逸-如何理解锁的多次可重入问题

  3. 深入浅出理解锁之—— AbstractQueuedSynchronizer

    深入浅出理解锁之-- AbstractQueuedSynchronizer 在Java中,多线程的情况下需要锁来保证数据的安全. 锁一般分为两类:sychronized 和 Lock sychroni ...

  4. 【java】 从hotspot底层对象结构理解锁膨胀升级过程

    文章目录 1.概述 2. 案例 2.1 对象分布 2.2 偏向锁 2.3 轻量级锁 2.4 重量级锁 M.扩展 1.概述 本文章是视频: 从hotspot底层对象结构理解锁膨胀升级过程 的笔记. 此文 ...

  5. 狂神JUC——8锁现象彻底理解锁

    JUC 1 狂神JUC--传统的Synchronized锁 2 狂神JUC--Lock锁 3 狂神JUC--Lock版生产者和消费者 4 狂神JUC--Synchronized版的生产者和消费者问题 ...

  6. Google Pixel 解锁BL、刷入Twrp、magisk Root、安装 Xposed

    Google Pixel 解锁 BL.刷入Twrp及Root :http://www.itfanr.cc/2018/10/16/google-pixel-unlock-bl-and-root/ Pix ...

  7. 酷派改变者S1(C105/C105-6/C105-8) 解锁BootLoader 并刷入recovery root

    首先下载好工具链接:https://pan.baidu.com/s/1qZjOCUw 密码:u2dr 备用下载链接:https://pan.baidu.com/s/1pMlmAef 本篇教程教你如何傻 ...

  8. 【面试 分布式锁详细解析】续命 自旋锁 看门狗 重入锁,加锁 续命 解锁 核心源码,lua脚本解析,具体代码和lua脚本如何实现

    Redisson实现分布式锁原理 自己实现锁续命 在 controller 里开一个 线程 (可以为 守护线程) 每10秒,判断一个 这个 UUID是否存在,如果 存在,重置为 30秒. 如果不存在, ...

  9. 青橙 M4 解锁BootLoader 并刷入recovery ROOT

    首先下载工具链接:https://pan.baidu.com/s/1o9xzTEi 密码:7s7a 备用连接:https://pan.baidu.com/s/1bq47TMn 本篇教程教你如何傻瓜式解 ...

最新文章

  1. 【C++】explicit 关键字
  2. Rigidbody.Is Kinematic和碰撞体
  3. mysql bench linux_MySQL Study之--Linux下安装MySQL workbench工具
  4. Spring框架----Spring的bean之三种创建bean对象的方式
  5. 利用Linux系统生成随机密码的8种方法
  6. SpringBoot读取配置文件
  7. paip.提升效率--数据绑定到table原理和流程Angular js jquery实现
  8. 远程桌面中转,基于 UltraVNC Repeater(中继器)的远程桌面服务搭建,用于复杂网络环境
  9. 【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置***帧以及动画创建!【二】...
  10. A simple brute force problem.
  11. 全自动采集程序 php,快看CMS全自动采集影视程序
  12. a站、b站、c站、d站、e站、f站、g站、h站、i站、j站、k站、l站、m站、n站…z站?...
  13. Cortex-A 架构
  14. 大地坐标与空间直角坐标系的相互转化
  15. 爱情公寓不为人知的创作历程
  16. 集体智慧编程——使用决策树发现潜在客户
  17. 为什么90后不鸟管理者,却愿意被大神虐?
  18. 聊一下面试经常问的SQL注入
  19. 给拯救者Y7000换个固态
  20. 基于Matlab——夫琅禾夫衍射以及菲涅尔衍射

热门文章

  1. firewalld的基础操作命令
  2. NearbyService超简单集成教程get!助你打造一款更加便捷的社交聊天类应用
  3. C#读写EXCEL源码提示“office检测到此文件存在一个问题。为帮助保护您的计算机,不能打开此文件。 ”的解决
  4. 【概率论基础进阶】数理统计的基本概念-常用统计分布
  5. 解决EasyExcel工具读取Excel空数据行的问题
  6. java计算机毕业设计花卉网站源码+mysql数据库+系统+lw文档+部署
  7. 智能合约安全审计公司选型分析和审计报告资源下载---国内篇
  8. 数据库索引和索引底层实现原理
  9. php sll邮箱注册_使用php发送电子邮件(phpmailer)
  10. office web apps java_整合Office Web Apps至自己的开发系统