死锁产生的四个必要条件
- 互斥:资源只能被一个线程持有,不能被多个线程同时共享。
- 请求与保持:线程已经持有了一个资源,在未释放该资源的情况下,又去请求获取另外一个资源。
- 不可剥夺:线程持有的资源,无法被其他线程强行剥夺,只能自己释放。
- 循环等待:多个线程之间形成一个「资源请求闭环」,每个线程都在等待下一个线程持有的资源,最终形成相互等待的局面。
如何避免?
🌟 只要破坏其中一个条件就行,但是其中互斥和不可剥夺一般无法改变,是加锁的固有属性。 常见的避免方法:
- 打破「循环等待条件」: 必须统一资源获取顺序,先资源A后资源B,不允许先资源B后资源A,这样能保证在线程1获取资源A和B的同时,线程2请求资源A的时候无法获取到,阻塞等待线程1执行完毕释放所有资源才可以继续,不然有可能会导致线程1在获取资源B的时候,被线程2先获取到资源B导致死锁的发生。
- 打破「请求与保持条件」: 线程2在请求资源B的时候设置超时,超过一定时间便取消执行,释放已获取到的资源B,让线程1可以获取到资源A继续执行,然后释放所有资源,线程2再次发起成功获取到资源A和资源B执行任务。