死锁详解:四个必要条件、Java 死锁排查与数据库死锁处理
死锁是多个执行单元永久等待彼此占有资源的状态。它同时需要四个条件:资源互斥;已持有资源时继续等待;资源不能被强制剥夺;等待关系形成环。破坏任一条件即可避免严格意义上的死锁。
最常用预防方式是建立全局锁顺序,所有线程都按同一顺序申请;也可一次性申请全部资源、使用可超时锁并失败回退、缩小临界区。银行家算法属于避免策略,通过判断分配后系统是否仍有安全序列决定是否批准,但需要预知最大需求,通用业务中较少直接使用。
检测可构建等待图:节点为线程或事务,边表示正在等待对方资源,图中出现环即有死锁候选。Java 可通过线程转储查看 BLOCKED 线程、持有锁与等待锁;数据库通常自动检测事务等待环,选择代价较小的事务回滚,应用必须正确重试整个事务。
死锁与饥饿、活锁不同。饥饿是长期得不到资源但系统仍前进;活锁是参与者不断响应却反复让步,没有有效进展。锁等待超时能恢复服务,却不代表根因已消失。
排查时记录锁名、获取顺序、持有时长和调用栈,并用一致顺序修复。误区是看到线程不动就断言死锁、在持锁时执行网络 I/O、重试单条 SQL 破坏事务语义,以及用更大的超时掩盖环。小结:设计阶段统一资源顺序,运行阶段保留等待证据,恢复阶段允许幂等重试。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Dai Wei!
评论

