Java发现死锁

发生死锁有4个必要条件,4个条件缺一不可:

1、互斥条件,共享资源在同一时刻只能被一个线程占用。

2、保持与请求条件,请求一把锁的时候还保持着另一把锁。

3、循环条件,线程的锁之间存在等待环路。

4、不剥夺条件,没有外界条件干扰锁的获取与释放。

下面是一个死锁的例子

class DeadLockDemo implements Runnable{

    int flag = 1;
    static Object lock1 = new Object();
    static Object lock2 = new Object();

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName()+"线程运行");
            if (flag == 1) {
                synchronized (lock1) {
                    Thread.sleep(500);
                    synchronized (lock2) {
                        System.out.println("线程1成功拿到两把锁");
                    }
                }
            }else if (flag == 0) {
                synchronized (lock2) {
                    Thread.sleep(500);
                    synchronized (lock1) {
                        System.out.println("线程2成功拿到两把锁");
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception{
        DeadLockDemo dl1 = new DeadLockDemo();
        DeadLockDemo dl2 = new DeadLockDemo();
        dl1.flag=1;
        dl1.flag=0;
        Thread t1 = new Thread(dl1);
        Thread t2 = new Thread(dl2);
        t1.start();
        t2.start();
    }
}

一段代码用到了多个锁,要避免以相反的顺序获取锁。如果死锁真的发生了,该如何检查出死锁呢?java提供了查找因死锁而阻塞的线程的方法。

ThreadMXBean是Java虚拟机线程系统的管理接口,Java虚拟机也提供了此接口的实现类,通过ManagementFactory.getThreadMXBean()获取实现类实例。使用findDeadlockedThreads()查找因死锁而阻塞的线程。

class DeadLockDemo implements Runnable{

    int flag = 1;
    static Object lock1 = new Object();
    static Object lock2 = new Object();

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName()+"线程运行");
            if (flag == 1) {
                synchronized (lock1) {
                    Thread.sleep(500);
                    synchronized (lock2) {
                        System.out.println("线程1成功拿到两把锁");
                    }
                }
            }else if (flag == 0) {
                synchronized (lock2) {
                    Thread.sleep(500);
                    synchronized (lock1) {
                        System.out.println("线程2成功拿到两把锁");
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception{
        DeadLockDemo dl1 = new DeadLockDemo();
        DeadLockDemo dl2 = new DeadLockDemo();
        dl1.flag=1;
        dl1.flag=0;
        Thread t1 = new Thread(dl1);
        Thread t2 = new Thread(dl2);
        t1.start();
        t2.start();

        // 睡眠1秒钟确保死锁发生
        TimeUnit.SECONDS.sleep(1);

        /**
         * 使用ThreadMXBean查找因死锁而阻塞的线程
         */
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        long[] dlt = threadMXBean.findDeadlockedThreads();
        if (dlt != null){
            for (int i=0; i<dlt.length; i++){
                ThreadInfo threadInfo = threadMXBean.getThreadInfo(dlt[i]);
                System.out.println("发现因死锁而阻塞的线程 "+threadInfo.getThreadName());
            }
        }
    }
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值