死锁终结者:顺序锁和轮询锁!(2)

简介: 死锁终结者:顺序锁和轮询锁!(2)

从上述结果可以看出,线程 1 和线程 2 都进入了死锁状态,相互都在等待对方释放锁。

从上述示例分析可以得出,产生死锁需要满足以下 4 个条件:


  1. 互斥条件:指运算单元(进程、线程或协程)对所分配到的资源具有排它性,也就是说在一段时间内某个锁资源只能被一个运算单元所占用。


  1. 请求和保持条件:指运算单元已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它运算单元占有,此时请求运算单元阻塞,但又对自己已获得的其它资源保持不放。


  1. 不可剥夺条件:指运算单元已获得的资源,在未使用完之前,不能被剥夺。


  1. 环路等待条件:指在发生死锁时,必然存在运算单元和资源的环形链,即运算单元正在等待另一个运算单元占用的资源,而对方又在等待自己占用的资源,从而造成环路等待的情况。


只有这 4 个条件同时满足,才会造成死锁的问题。


那么也就是说,要产生死锁必须要同时满足以上 4 个条件才行,那我们就可以通过破坏任意一个条件来解决死锁问题了。


死锁解决方案分析


接下来我们来分析一下,产生死锁的 4 个条件,哪些是可以破坏的?哪些是不能被破坏的?


  • 互斥条件:系统特性,不能被破坏。


  • 请求和保持条件:可以被破坏。


  • 不可剥夺条件:系统特性,不能被破坏。


  • 环路等待条件:可以被破坏。


通过上述分析,我们可以得出结论,我们只能通过破坏请求和保持条件或者是环路等待条件,从而来解决死锁的问题,那上线,我们就先从破坏“环路等待条件”开始来解决死锁问题。


解决方案1:顺序锁


所谓的顺序锁指的是通过有顺序的获取锁,从而避免产生环路等待条件,从而解决死锁问题的。


当我们没有使用顺序锁时,程序的执行可能是这样的:


微信图片_20220120214059.jpg


线程 1 先获取了锁 A,再获取锁 B,线程 2 与 线程 1 同时执行,线程 2 先获取锁 B,再获取锁 A,这样双方都先占用了各自的资源(锁 A 和锁 B)之后,再尝试获取对方的锁,从而造成了环路等待问题,最后造成了死锁的问题。


此时我们只需要将线程 1 和线程 2 获取锁的顺序进行统一,也就是线程 1 和线程 2 同时执行之后,都先获取锁 A,再获取锁 B,执行流程如下图所示:


微信图片_20220120214141.jpg


因为只有一个线程能成功获取到锁 A,没有获取到锁 A 的线程就会等待先获取锁 A,此时得到锁 A 的线程继续获取锁 B,因为没有线程争抢和拥有锁 B,那么得到锁 A 的线程就会顺利的拥有锁 B,之后执行相应的代码再将锁资源全部释放,然后另一个等待获取锁 A 的线程就可以成功获取到锁资源,执行后续的代码,这样就不会出现死锁的问题了。



相关文章
|
6月前
|
安全 算法 Java
可重入锁,不可重入锁,死锁的多种情况,以及产生的原因,如何解决,synchronized采用的锁策略(渣女圣经)自适应的底层,锁清除,锁粗化,CAS的部分应用
可重入锁,不可重入锁,死锁的多种情况,以及产生的原因,如何解决,synchronized采用的锁策略(渣女圣经)自适应的底层,锁清除,锁粗化,CAS的部分应用
|
3月前
|
Go
并发陷阱:死锁、活锁和饥饿
并发陷阱:死锁、活锁和饥饿
26 0
|
4月前
|
Linux
Linux线程同步(try锁和读写锁)
Linux线程同步(try锁和读写锁)
33 0
|
4月前
|
Java 编译器 程序员
synchronized 原理(锁升级、锁消除和锁粗化)
synchronized 原理(锁升级、锁消除和锁粗化)
|
10月前
|
安全 Java 测试技术
【JUC中的 “8锁现象” 】 —— 每天一点小知识
【JUC中的 “8锁现象” 】 —— 每天一点小知识
【JUC中的 “8锁现象” 】 —— 每天一点小知识
|
11月前
|
运维 Oracle 关系型数据库
Oracle优化02-锁和阻塞
Oracle优化02-锁和阻塞
85 0
|
Java 编译器
Java多线程【锁优化与死锁】
Java多线程【锁优化与死锁】
Java多线程【锁优化与死锁】
锁消除、锁粗化、锁升级区别与联系
锁消除、锁粗化、锁升级区别与联系
锁消除、锁粗化、锁升级区别与联系
并发锁(一):为什么要加锁
并发锁(一):为什么要加锁
132 0
并发锁(一):为什么要加锁
|
存储 安全 Java
看完你就明白的锁系列之锁的状态
前面两篇文章我介绍了一下 看完你就应该能明白的悲观锁和乐观锁 看完你就明白的锁系列之自旋锁 看完你就会知道,线程如果锁住了某个资源,致使其他线程无法访问的这种锁被称为悲观锁,相反,线程不锁住资源的锁被称为乐观锁,而自旋锁是基于 CAS 机制实现的,CAS又是乐观锁的一种实现,那么对于锁来说,多个线程同步访问某个资源的流程细节是否一样呢?换句话说,在多线程同步访问某个资源时,锁的状态会如何变化呢?本篇文章来探讨一下。
78 0
看完你就明白的锁系列之锁的状态

相关实验场景

更多