死锁的四个必要条件:请求和保持、互斥、不可剥夺、循环等待。
-死锁条件-----破除方法--
请求和保持 : 预先分配
互斥:虚拟资源
不可剥夺:可剥夺,死锁检测之后就中止最后导致死锁的进程
循环等待:按序申请资源
1. 正确的顺序获得锁
如果必须获取多个锁,我们就要考虑不同线程获取锁的顺序。
上面的例子出现死锁的根本原因就是获取所的顺序是乱序的,超乎我们控制的。上面例子最理想的情况就是把业务逻辑抽离出来,把获取锁的代码放在一个公共的方法里面,让这两个线程获取锁都是从我的公共的方法里面获取。
2. 超时放弃
当线程获取锁超时了则放弃,这样就避免了出现死锁获取的情况。当使用synchronized关键词提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去,然而Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放之前已经获得的所有的锁。通过这种方式,也可以很有效地避免死锁。