避免死锁

死锁概念

基本概念->翻我牌子来看

如何避免死锁

  • 三种用于避免死锁的技术:

    1. 加锁顺序(线程按照一定的顺序加锁)

      (1)再多线程中,如果一个线程需要锁,那么他就必须要按照一定顺序获得锁

      “`
      thread a
      lock 1
      lock 2

      thread b
          等待 1//等待线程a中1加锁后才能对3上锁        
          lock 3(1已经被上锁)
      
      thread c
          //如果想获取锁1,2,3,则
          等待 1
          等待 2
          等待 3
          //然后才轮到该线程获取
      ```
      

      (2)缺点:按照顺序加锁是一种有效的死锁预防机制,这种方式需要你事先知道所有可能会用到的锁和锁的顺序,但这个很难,并不一定所有的都能知道。

    2. 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)

      • 在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求。

      • 若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试

      • 这段随机的等待时间让其它线程有机会尝试获取相同的这些锁,并且让该应用在没有获得锁的时候可以继续运行(可以做些其他的事)

      • 缺点:有时为了执行某个任务。某个线程花了很长的时间去执行任务,如果在其他线程看来,可能这个时间已经超过了等待的时限,可能出现了死锁。

    3. 死锁检测

      • 死锁检测是一个更好的预防死锁机制,针对的是那些不可能按序加锁且锁超时不可行的场景

      • 每当线程获取了锁,会在线程和锁相关的数据结构(map、graph等)中,同样,线程请求锁也需要记录在这个数据结构中

      • 当一个线程请求失败时,这个线程可以遍历锁的关系图看看是否有死锁发生,死锁一般要比两个线程互相持有对方的锁这种情况要复杂的多

      • 当检测出死锁时,一个可行的做法是释放所有锁,回退,并且等待一段随机的时间后重试,更好的方案是给这些线程设置优先级,让一个(或几个)线程回退,剩下的线程就像没发生死锁一样继续保持着它们需要的锁。

最具有代表性的避免死锁算法是–> 银行家算法

猜你喜欢

转载自blog.csdn.net/wsq119/article/details/82284790