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

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

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

网购优惠券 https://m.fenfaw.cn/

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

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源码,了解其支持可重入的原理。

延伸阅读与参考资料

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

关于作者

关注公众号【庸人技术笑谈】,获取及时文章更新。记录平凡人的技术故事,分享有品质(尽量)的技术文章,偶尔也聊聊生活和理想。不贩卖焦虑,不做标题党。

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

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

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

  2. 并发王者课-铂金1:探本溯源-为何说Lock接口是Java中锁的基础

    欢迎来到<并发王者课>,本文是该系列文章中的第14篇. 在黄金系列中,我们介绍了并发中一些问题,比如死锁.活锁.线程饥饿等问题.在并发编程中,这些问题无疑都是需要解决的.所以,在铂金系列文 ...

  3. 并发王者课-铂金2:豁然开朗-“晦涩难懂”的ReadWriteLock竟如此妙不可言

    欢迎来到<并发王者课>,本文是该系列文章中的第15篇. 在上篇文章中,我们介绍了Java中锁的基础Lock接口.在本文中,我们将介绍Java中锁的另外一个重要的基本型接口,即ReadWri ...

  4. 铂金03:一劳永逸-如何理解锁的可重入问题

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

  5. 并发王者课-黄金3:雨露均沾-不要让你的线程在竞争中被“饿死”

    欢迎来到<并发王者课>,本文是该系列文章中的第13篇. 在上篇文章中,我们介绍了避免死锁的几种策略.虽然死锁臭名昭著,然而在并发编程中,除了死锁之外,还有一些同样重要的线程活跃性问题值得关 ...

  6. 并发王者课-青铜10:千锤百炼-如何解决生产者与消费者经典问题

    欢迎来到<并发王者课>,本文是该系列文章中的第10篇. 在本篇文章中,我将为你介绍并发中的经典问题-生产者与消费者问题,并基于前面系列文章的知识点,通过wait.notify实现这一问题的 ...

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

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

  8. java 变量锁_并发编程高频面试题:可重入锁+线程池+内存模型等(含答案)

    对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一.因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统.内存.CPU.编程语言等多方面的基础能力,更为考验一个程序 ...

  9. 【java】动态高并发时为什么推荐重入锁而不是Synchronized?

    1.概述 转载:http://www.dreamwu.com/post-1758.html 这个图画的不错,有助于加深理解. [Java]Synchronized 有几种用法 [java] 从hots ...

最新文章

  1. IROS 2021 | 激光视觉融合新思路?Lidar强度图+VPR
  2. java7 javascript引擎_Java7中脚本引擎的一般用法,共三种方法获得JavaScript引擎:名称、文件扩展名、MIME类型 | 学步园...
  3. Chrome浏览器不支持字体小于12px的解决办法
  4. linux shell脚本无法执行,报错syntax error near unexpected token `$'\r''解决方法
  5. 政府数据集中异地备份概述
  6. node中异步IO的理解
  7. 静态链接库LIB和动态链接库DLL的区别 创建和示例
  8. springboot链接数据库的bug
  9. Oracle logmnr使用
  10. 滚石杂志选出500张最强专辑
  11. excel如何转化成word文件
  12. html唱片机效果,黑胶唱片风格音频播放器jQuery插件
  13. Evevt Loop 事件循环
  14. 28BYJ-48步进电机
  15. 视觉软件工程师具体的工作内容是什么?
  16. Mysql 内存管理及优化
  17. java源程序编译型_Java语言的源程序不是编译型的,而是编译解释型的。( )_学小易找答案...
  18. 软件项目管理 6.10.成本预算
  19. 年度团队个人回顾工坊实录
  20. net mysql反斜杠怎么入库_MySQL中如何插入反斜杠,反斜杠被吃掉,反斜杠转义

热门文章

  1. 小米5s plus android8,小米加速小米5s/5s Plus机型安卓8.0适配
  2. 别再逼三星了,它在起死回生的路上挣扎很久了...
  3. 常用浏览器安装代理插件(SwitchyOmega)
  4. element 手机适配_解决vue移动端适配问题
  5. C++第一阶段项目《小公举养成记》
  6. 早些年ETC设备都要2000块钱一个,现在办理广发卡免费送,钱从哪里来的呢?
  7. fwr310刷openwrt_[转载]迅捷FWR310无线路由器的刷机
  8. oracle数据库建表
  9. python代码变成手机软件_三款可以在安卓手机上运行Python代码的软件
  10. Android实践——使用Bmob实现登录、注册等功能