死锁

死锁产生原因:

  1. 当前线程拥有其他线程需要的资源
  2. 当前线程等待其他线程已拥有的资源
  3. 都不放弃自己拥有的资源
public class LeftRightDeadlock {
    private final Object left = new Object();
    private final Object right = new Object();
 
    public void leftRight() {
        // 得到left锁
        synchronized (left) {
            // 得到right锁
            synchronized (right) {
                doSomething();
            }
        }
    }
 
    public void rightLeft() {
        // 得到right锁
        synchronized (right) {
            // 得到left锁
            synchronized (left) {
                doSomethingElse();
            }
        }
    }
}

      线程A调用leftRight()方法,得到left锁,同时线程B调用rightLeft()方法,得到right锁;线程A和线程B都继续执行,此时线程A需要right锁才能继续往下执行。

     此时线程B需要left锁才能继续往下执行。但是:线程A的left锁并没有释放,线程B的right锁也没有释放。所以他们都只能等待,而这种等待是无期限的-->永久等待-->死锁。

产生死锁的必要条件:

互斥条件、请求和保持条件、不可抢占条件、循环等待条件

处理死锁的思路:

  • 预防死锁:破坏死锁的四个必要条件中的一个或多个。(破坏请求和保持条件、破坏不可抢占条件、破坏循环等待条件)
  • 避免死锁:在资源动态分配过程中,用某种方式防止系统进入不安全的状态。
  • 检测死锁:是否出现环。
  • 解除死锁:通常撤销进程,回收资源,再分配给正处于阻塞状态的进程。

从Java层面预防死锁

  • 线程之间交错执行-》以固定的顺序加锁。
  • 执行某方法时就需要持有锁,且不释放-》缩减同步代码块范围,最好仅操作共享变量时才加锁。
  • 永久等待-》使用tryLock()定时锁,超过时限则返回错误信息.

  

原文地址:https://www.cnblogs.com/kikis/p/9770727.html