死锁(deadlock)
线程死锁的必备要素
- 互斥条件:进程要求对所分配的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待;
- 不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放,如 yield 释放 CPU 执行权);
- 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放;
- 循环等待条件:指在发生死锁时,必然存在一个线程请求资源的环形链,即线程集合 {T0,T1,T2,…Tn}中的 T0 正在等待一个 T1 占用的资源,T1 正在等待 T2 占用的资源,以此类推,Tn 正在等待己被 T0 占用的资源。
死锁的实现
/** * @author wsy */ public class DeadLockDemo { public static Object objectA = new Object(); public static Object objectB = new Object(); public static void main(String[] args) { Thread thread1 = new Thread(new Runnable() { @Override public void run() { sysObjectA(); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { sysObjectB(); } }); thread1.start(); thread2.start(); } public static void sysObjectA() { synchronized (objectA) { System.out.println(Thread.currentThread().getName() + "线程持有锁A"); System.out.println(Thread.currentThread().getName() + "申请锁B"); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (objectB) { System.out.println(Thread.currentThread().getName() + "线程持有锁B"); } } } public static void sysObjectB() { synchronized (objectB) { System.out.println(Thread.currentThread().getName() + "线程持有锁B"); System.out.println(Thread.currentThread().getName() + "申请锁A"); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (objectA) { System.out.println(Thread.currentThread().getName() + "线程持有锁A"); } } } }
死锁排查
输入jps查出当前运行的java进程号码
使用jstack+进程号码现实堆栈信息
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?