如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生 。
看下面这个例子:
Thread 1: lock A lock BThread 2: wait for A lock C (when A locked)Thread 3: wait for A wait for B wait for C如果一个线程(比如线程3)需要一些锁,那么它必须按照确定的顺序获取锁 。它只有获得了从顺序上排在前面的锁之后,才能获取后面的锁 。例如,线程2和线程3只有在获取了锁A之后才能尝试获取锁C(译者注:获取锁A是获取锁C的必要条件) 。因为线程1已经拥有了锁A,所以线程2和3需要一直等到锁A被释放 。然后在它们尝试对B或C加锁之前,必须成功地对A加了锁 。
按照顺序加锁是一种有效的死锁预防机制 。
但是,这种方式需要你事先知道所有可能会用到的锁(译者注:并对这些锁做适当的排序),但总有些时候是无法预知的 。
加锁时限另外一个可以避免死锁的方法是在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求 。若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试 。这段随机的等待时间让其它线程有机会尝试获取相同的这些锁,并且让该应用在没有获得锁的时候可以继续运行(译者注:加锁超时后可以先继续运行干点其它事情,再回头来重复之前加锁的逻辑) 。
以下是一个例子,展示了两个线程以不同的顺序尝试获取相同的两个锁,在发生超时后回退并重试的场景:
Thread 1 locks AThread 2 locks BThread 1 attempts to lock B but is blockedThread 2 attempts to lock A but is blockedThread 1's lock attempt on B times outThread 1 backs up and releases A as wellThread 1 waits randomly (e.g. 257 millis) before retrying.Thread 2's lock attempt on A times outThread 2 backs up and releases B as wellThread 2 waits randomly (e.g. 43 millis) before retrying.在上面的例子中,线程2比线程1早200毫秒进行重试加锁,因此它可以先成功地获取到两个锁 。这时,线程1尝试获取锁A并且处于等待状态 。当线程2结束时,线程1也可以顺利的获得这两个锁(除非线程2或者其它线程在线程1成功获得两个锁之前又获得其中的一些锁) 。需要注意的是,由于存在锁的超时,所以我们不能认为这种场景就一定是出现了死锁 。也可能是因为获得了锁的线程(导致其它线程超时)需要很长的时间去完成它的任务 。
此外,如果有非常多的线程同一时间去竞争同一批资源,就算有超时和回退机制,还是可能会导致这些线程重复地尝试但却始终得不到锁 。如果只有两个线程,并且重试的超时时间设定为0到500毫秒之间,这种现象可能不会发生,但是如果是10个或20个线程情况就不同了 。因为这些线程等待相等的重试时间的概率就高的多(或者非常接近以至于会出现问题) 。(译者注:超时和重试机制是为了避免在同一时间出现的竞争,但是当线程很多时,其中两个或多个线程的超时时间一样或者接近的可能性就会很大,因此就算出现竞争而导致超时后,由于超时时间一样,它们又会同时开始重试,导致新一轮的竞争,带来了新的问题 。)
这种机制存在一个问题,在JAVA中不能对synchronized同步块设置超时时间 。你需要创建一个自定义锁,或使用Java5中java.util.concurrent包下的工具 。写一个自定义锁类不复杂,但超出了本文的内容 。后续的Java并发系列会涵盖自定义锁的内容 。
死锁检测死锁检测是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景 。
每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下 。
除此之外,每当有线程请求锁,也需要记录在这个数据结构中 。
当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生 。
推荐阅读
- 兆 宽带中的“M”是什么意思?
- 绿豆汤为什么煮出来是红色的有毒吗 北方绿豆汤为什么煮出来是红色的
- 蚊子怕空调冷风吗 为什么蚊子怕空调
- 如何自己动手更换运营商宽带光猫,需要注意什么?
- 飞机的轨道是什么样的 飞机飞行的轨道是怎么样的
- 方便面面算不算垃圾食品 请问方便面是属于垃圾食品吗
- 50年代红印圆茶,鼎兴圆茶是什么茶
- |三十多岁女子出轨,起因是老公出国出差,难道就不值得同情嘛
- 柯基和哈士奇配出来的狗是什么样的 哈士奇和主人吵架
- 安化天尖黑茶功效,安化黑茶的含梗量是多少
