产生死锁的四个必要条件
四个必要条件
互斥条件:该资源任意⼀个时刻只由⼀个线程占⽤。
请求和保持条件:⼀个进程因请求资源⽽阻塞时,对已获得的资源保持不放。
不剥夺条件:线程已获得的资源在末使⽤完之前不能被其他线程强⾏剥夺,只有⾃⼰使⽤完 毕后才释放资源。
循环等待条件::若⼲进程之间形成⼀种头尾相接的循环等待资源关系。
代码演示
package com.lzp.test; /** * @Author 14715 * @Date 2022/6/6 16:21 * @Version 1.0 * * 死锁Demo */ public class DeadLockDemo { private static Object resource1 = new Object();//资源 1 private static Object resource2 = new Object();//资源 2 public static void main(String[] args) { new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread().getName() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread().getName() + "get resource2"); } } }, "线程 1").start(); new Thread(() -> { synchronized (resource2) { System.out.println(Thread.currentThread().getName() + "get resource2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "waiting get resource1"); synchronized (resource1) { System.out.println(Thread.currentThread().getName() + "get resource1"); } } }, "线程 2").start(); } }
运行结果
修改线程2的代码如下——破坏循环等待条件
package com.lzp.test; /** * @Author 14715 * @Date 2022/6/6 16:21 * @Version 1.0 * * 死锁Demo */ public class DeadLockDemo { private static Object resource1 = new Object();//资源 1 private static Object resource2 = new Object();//资源 2 public static void main(String[] args) { new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread().getName() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread().getName() + "get resource2"); } } }, "线程 1").start(); new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread().getName() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread().getName() + "get resource2"); } } }, "线程 2").start(); } }
运行结果
避免死锁的发生
- 破坏互斥条件 :这个条件我们没有办法破坏,因为我们⽤锁本来就是想让他们互斥的(临界 资源需要互斥访问)。
- 破坏请求与保持条件 :⼀次性申请所有的资源。
- 破坏不剥夺条件 :占⽤部分资源的线程进⼀步申请其他资源时,如果申请不到,可以主动释 放它占有的资源。
- 破坏循环等待条件 :靠按序申请资源来预防。按某⼀顺序申请资源,释放资源则反序释放。 破坏循环等待条件。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能