Content #
基本上死锁的发生是因为:
- 互斥条件,类似 Java 中 Monitor 都是独占的,要么是我用,要么是你用。
- 互斥条件是长期持有的,在使用结束之前,自己不会释放,也不能被其他线程抢占。
- 循环依赖关系,两个或者多个个体之间出现了锁的链条环。
所以,我们可以据此分析可能的避免死锁的思路和方法。
- 尽量避免使用多个锁,并且只有需要时才持有锁。
嵌套的 synchronized 或者 lock 非常容易出问题。
- 如果必须使用多个锁,尽量设计好锁的获取顺序。
一般的情况,我建议可以采取些简单的辅助手段,比如:将对象(方法)和锁之间的关系,用图形化的方式表示分别抽取出来。然后根据对象之间组合、调用的关系对比和组合,考虑可能调用时序。按照可能时序合并,发现可能死锁的场景。
- 使用带超时的方法,为程序带来更多可控性。
类似 Object.wait(…) 或者 CountDownLatch.await(…),都支持所谓的 timed_wait,我们完全可以就不假定该锁一定会获得,指定超时时间,并为无法得到锁时准备退出逻辑。
- 通过静态代码分析(如 FindBugs)去查找固定的模式,进而定位可能的死锁或者竞争情况。