JAVA - 死锁
JAVA - 死锁
死锁示例
public class LockTest { public static void main(String[] args) { Object resource1 = new Object(); Object resource2 = new Object(); new Thread(() -> { synchronized (resource1){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("已获取资源1,准备获取资源2"); synchronized (resource2){ System.out.println("成功获取资源2"); } } }, "线程1").start(); new Thread(() -> { synchronized (resource2){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("已获取资源2,准备获取资源1"); synchronized (resource1){ System.out.println("成功获取资源1"); } } }, "线程2").start(); } }
如何预防和避免线程死锁?
如何预防死锁? 破坏死锁的产生的必要条件即可:
- 破坏请求与保持条件 :一次性申请所有的资源。
- 破坏不剥夺条件 :占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
- 破坏循环等待条件 :靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。
如何避免死锁?
避免死锁就是在资源分配时,借助于算法(比如银行家算法)对资源分配进行计算评估,使其进入安全状态。
安全状态 指的是系统能够按照某种进程推进顺序(P1、P2、P3.....Pn)来为每个进程分配所需资源,直到满足每个进程对资源的最大需求,使每个进程都可顺利完成。称<P1、P2、P3.....Pn>序列为安全序列。
死锁的四个条件
互斥:资源必须处于非共享模式,即一次只有一个进程可以使用。如果另一进程申请该资源,那么必须等待直到该资源被释放为止。
占有并等待:一个进程至少应该占有一个资源,并等待另一资源,而该资源被其他进程所占有。
非抢占:资源不能被抢占。只能在持有资源的进程完成任务后,该资源才会被释放。
循环等待:有一组等待进程 {P0, P1,..., Pn}
, P0
等待的资源被 P1
占有,P1
等待的资源被 P2
占有,......,Pn-1
等待的资源被 Pn
占有,Pn
等待的资源被 P0
占有。
参考:
https://javaguide.cn/java/concurrent/java-concurrent-questions-01/#认识线程死锁
本文作者:护发师兄
本文链接:https://www.cnblogs.com/jonil/p/15940505.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步