死锁问题整理

1 死锁的产生条件

  • 资源互斥,每个资源一次只能被一个线程持有
  • 资源不可抢夺
  • 占用并等待资源,涉及的线程当前至少持有一个资源并申请其他资源,而这些资源恰好被其他线程持有
  • 循环等待资源

2 死锁的排查

Jstack、arthas、jvisualvm 直接检查

3 如何解决

3.1 已经产生

重启

3.2 修复

从占用并等待资源和循环等待资源角度考虑

  • 锁粗法
    用一个粗粒度的锁代替原来多个细粒度的锁,这样每个线程只申请一个锁,避免了死锁。
    但是这个方法会导致资源浪费。避免了“循环等待资源”的必要条件。
  • 锁排序法
    相关线程使用全局统一的顺序申请锁,消除“循环等待资源”的必要条件,比如一个对象方法要申请两个锁,先申请hashcode值小的那个锁,然后再申请hashcode值大的那个锁。如果存在两个锁的hashcode相同,可以退化成粗锁法。
    “循环等待资源”实际为每个对象使用局部顺序去申请锁,如果依赖全局统一的顺序,即可消除“循环等待资源”的必要条件。
  • ReentrantLock.tryLock(long, TimeUnit),为申请锁这个操作指定一个超时时间
    避免了“占用并等待资源”的必要条件。
  • 开放调用
    一个方法在调用外部方法时不持有任何锁。避免了“占用并等待资源”的必要条件。
  • 不用锁
原文地址:https://www.cnblogs.com/lllliuxiaoxia/p/15689367.html