Java死锁分析

死锁是多进程环境下的一种假死现象,即产生死锁的进程都处于等待状态。只要满足了下面四个必要条件,就有可能产生死锁:

  1. 互斥条件:进程对所分配到的资源不允许其他进程进行访问,若其他进程访问该资源,只能等待,直至占有该资源的进程使用完成后释放该资源
  2. 请求和保持条件:进程获得一定的资源之后,又对其他资源发出请求,但是该资源可能被其他进程占有,此事请求阻塞,但又对自己获得的资源保持不放
  3. 不可剥夺条件:是指进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完后自己释放
  4. 环路等待条件:是指进程发生死锁后,必然存在一个进程–资源之间的环形链

一旦产生了死锁,程序将不再往下执行。那么应该怎么分析程序是否产生了死锁呢?本节来介绍一种使用Java Dump分析死锁的方法。

1.包含死锁的程序

下面是一段包含死锁的程序:DeadLock.java

public class DeadLock {
    final Object lockA = new Object();
    final Object lockB = new Object();
    public static void main(String[] args) {
        DeadLock demo = new DeadLock();
        demo.startLock();
    }
    public void startLock(){
        ThreadA a= new ThreadA(lockA,lockB);
        ThreadB b= new ThreadB(lockA,lockB);
        //start threads
        a.start();
        b.start();
    }
}

class ThreadA extends Thread{
    private Object lockA = null;
    private Object lockB = null;
    public ThreadA(Object a, Object b){
        this.lockA = a;
        this.lockB = b;
    }
    public void run() {
        synchronized (lockA) {
            System.out.println("*** Thread A: ***: Lock A" );
            try {
                sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lockB) {
                System.out.println("*** Thread A: ***: Lock B" );
            }
        }
        System.out.println("*** Thread A: ***: Finished" );
    }
}

class ThreadB extends Thread{
    private Object lockA = null;
    private Object lockB = null;
    public ThreadB(Object a, Object b){
        this.lockA = a;
        this.lockB = b;
    }
    public void run() {
        synchronized (lockB) {
            System.out.println("*** Thread B: ***: Lock B" );
            try {
                sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lockA) {
                System.out.println("*** Thread B: ***: Lock A" );
            }
        }
        System.out.println("*** Thread B: ***: Finished" );
    }
}

说明:以上代码中,有两个共享资源lockA和lockB,同时启动两个线程a和b,其中线程a先申请资源lockA,然后睡3秒,再去申请资源lockB;线程b先申请资源lockB,然后也睡3秒,再去申请资源lockA。当线程a启动并申请到资源lockA然后睡3秒时,这时线程b启动并申请到资源lockB也睡3秒;等线程a睡醒后去申请资源lockB,发现资源lockB被其他线程占用,所以线程a就开始等待;等线程b睡醒后去申请资源lockA,发现资源lockA也被其他线程占用,然后线程b也开始等待。如此这般,a和b就进入了循环等待的死锁状态。

2.使用JDK的Thread Dump工具分析死锁

这里介绍一种在Windows和Linux下,使用JDK提供的Thread Dump工具分析死锁的办法。

1.Windows下使用Thread Dump分析死锁

(1)编译并执行DeadLock.java程序

image

(2)按Ctrl + Break(或者fn + b)分析死锁

image
image

2.Linux下使用Thread Dump分析死锁

(1)编译并执行DeadLock.java程序

image

(2)使用kill -3 PID分析死锁

新打开一个终端,查看jps进程号,使用kill -3 PID杀死死锁进程:

image

原来的终端窗口会显示检测到的死锁信息:

image

死锁分析是一门非常重要的技术手段。使用Thread Dump工具可以方便的检测出程序是否包含死锁。

本节介绍了Java中使用Thread Dump工具分析死锁的详细过程。祝你玩的愉快!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 什么是死锁? 死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进...
    小母牛不生产奶阅读 1,558评论 0 0
  • 一、死锁的定义 多线程以及多进程改善了系统资源的利用率并提高了系统 的处理能力。然而,并发执行也带来了新的问题——...
    菜菜爱吃菜呀阅读 4,017评论 0 2
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 7,216评论 1 15
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 8,122评论 1 18
  • 在之前的课程中,我们已经学习了进程相关的知识。进程是计算机程序被执行的一个实例(instance),一个进程可能由...
    夏威夷的芒果阅读 4,545评论 0 2

友情链接更多精彩内容