Java 死锁的概念及排查

本文深入探讨了Java中的死锁问题,解释了死锁的四个必要条件:互斥、不可剥夺、请求与保持、循环等待。提出了预防死锁的策略,包括破坏这些条件,并介绍了银行家算法来避免死锁。此外,还通过Java模拟死锁展示了死锁的发生,并讲解了如何使用jps和jstack工具进行死锁排查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是死锁

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。

  • 互斥条件:资源是独占的且排他使用,进程互斥使用资源,即任意时刻一个资源只能给一个进程使用,其他进程若申请一个资源,而该资源被另一进程占有时,则申请者等待直到资源被占有者释放。
  • 不可剥夺条件:进程所获得的资源在未使用完毕之前,不被其他进程强行剥夺,而只能由获得该资源的进程资源释放。
  • 请求和保持条件:进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。
  • 循环等待条件:在发生死锁时必然存在一个进程等待队列{P1,P2,…,Pn},其中P1等待P2占有的资源,P2等待P3占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路,环路中每一个进程所占有的资源同时被另一个申请,也就是前一个进程占有后一个进程所深情地资源。

预防死锁

我们可以通过破坏死锁产生的4个必要条件来 预防死锁,由于资源互斥是资源使用的固有特性是无法改变的。

  1. 破坏“不可剥夺”条件:一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式的释放重新加入到 系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。
  2. 破坏”请求与保持条件“:第一种方法静态分配即每个进程在开始执行时就申请他所需要的全部资源。第二种是动态分配即每个进程在申请所需要的资源时他本身不占用系统资源。
  3. 破坏“循环等待”条件:采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。

避免死锁

进行银行家算法检查算法判断是否处于安全状态,安全状态继续运行,不安全状态拒绝资源请求分配,然后继续执行。

Java模拟死锁

import java.util.concurrent.TimeUnit;

public class DeadLockDemo {
    public static void main(String[] args) {
        String lockA = "lockA";
        String lockB = "lockB";
        new Thread(new DeadLock(lockA, lockB),"Thread1").start();
        new Thread(new DeadLock(lockB, lockA),"Thread2").start();
    }
}

class DeadLock implements Runnable{
    private String lockA; //锁A
    private String lockB; //锁B

    public DeadLock(String lockA, String lockB) {
        this.lockA = lockA;
        this.lockB = lockB;
    }

    @Override
    public void run() {
        // 锁A
        synchronized (lockA) {
            System.out.println(Thread.currentThread().getName()+" 持有:" + lockA + ",尝试获取:" + lockB);
            // 休眠一下
            try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}
            // 锁B
            synchronized (lockB) {
                System.out.println(Thread.currentThread().getName()+" 持有:" + lockB + ",尝试获取:" + lockA);
            }
        }
    }
}

结果

排查死锁

这是一个简单的Demo,在实际生产中情况要比这个复杂的多,而且仅靠一张照片没有说服力,得拿出证据。

Java 提供的有 jsp 和 jstack 工具,可以配合使用找出故障原因。

jps -l

jstakc 进程号

这个截图充分说明了错误产生的原因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值