所谓的线程死锁就是指多个线程因为竞争资源而造成的一种僵局,一个线程不停的申请锁,释放锁,从而不给另外的线程,获得资源的机会,这就是死锁问题。若没有外力的作用,那么这些线程偶会卡到这里无法推进。
产生死锁的必要条件:
1:互斥条件:进程要求对分配的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占有,此时若有其他进程请求该资源,则请求进程只能等待
2:不剥夺条件:进程所获得资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放
3:请求和保持条件:进程已经保持了至少一个资源,但又提出新的资源请求,而该资源已经被其他进程占有,此时请求进程被阻塞,但对自己已经获得的资源保持不释放
4:循环等待条件:存在一种进程资源循环等待链,链中每一个进程已获得的资源同时被链中选图个进程所请求,即存在一个处于等待状态的进程集合
如何避免死锁
1:加锁顺序(线程按照一定的顺序加锁)
按照顺序加锁是一种有效的预防死锁的方法,但是这种方法需要你事先知道所有可能用到的锁,并且对这些锁做适当的安排(在实际情况中,有些情况是无法预知的)
2:加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
若一个线程没有在给定时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段时间再重试,这段随机等待时间让其他线程有机会尝试获取相同的这些锁,并且让该应用在没有获得锁的时候可以继续运行
(需要注意:由于存在锁的超时,不一定就是出现了死锁,有可能是获得锁的线程,需要很长一段时间来完成它的任务)
3:死锁检测
死锁检测是一个更好的预防死锁的方法,它主要针对那些不可能实现按序加锁并且加锁超时也不适合的情况
每当一个线程获得了锁,会在线程和锁相关的数据结构中将它记下来,另外,有其他线程请求锁,也需要记录在这数据结构中,当一个线程请求锁失败的时候,这个线程可以遍历锁的关系看看是否存在死锁发生