如何避免死锁
2020-12-01 本文已影响0人
squirrels
避免死锁主要有 3种方式
- 加锁顺序
- 加锁时限
- 死锁检测
加锁顺序
一个线程如果要获取多个锁,必须按照一定的顺序去获取,比如要获取A B C 三把锁,我们规定,必须获取到了 AB 两把锁,才能去获取 C锁
举个例子 现在有两个线程 都要去获取 ABC 三把锁
然后 1号 线程 获取到了 A 和 B 两把锁
2号 线程获取了 C锁
于是 1号线程在等待 2号线程释放锁C锁
2号线程在等待 1 号线程释放 A 和 B 锁
于是出现了死锁
现在采用加锁队列后,必须先 获取 A 和 B 才能获取C锁,所以 2号线程就没有机会在没有获取 AB 的情况下拿到C锁,就不会出现死锁问题
这个策略的最大问题是,你必须提前知道所有用到的锁,这个有些时候难以预测
加锁时限
一个线程尝试去获取锁,如果在指定的时间内获取不到,就放弃等待锁,并释放自己现在所持有的锁,然后随机等待一定时间,再去获取锁
这里要注意的是 ,等待的时间一定要是随机,不然可能出现 两个线程都释放资源,然后等待相同时间,然后再一起去获取锁,于是又死锁,这种现象称为活锁
死锁检测
利用数据结构,如 一个map,然后每次线程的上锁,和获取不到锁,都记录在里面,当一个线程获取不到锁的时候,就去便利查看这个map,看一下有没有死锁,有的话就将整个map里所有的锁全部释放,然后各个线程稍作等待,再去竞争锁。
这里还可以优化下,设置优先级,释放所有锁的时候,不释放优先级高的锁,能提高性能。