JAVA多线程——死锁分析

线程死锁的原因:当两个或多个线程正在等待对方占有的锁,死锁就会发生

死锁会导致两个线程无法继续运行,被永远挂起。


简单的死锁例子

创建两个互相等待对方释放锁的线程

public class DeadLock1 implements Runnable {

    private Object o1, o2;

    public DeadLock1(Object o1, Object o2) {
        this.o1 = o1;
        this.o2 = o2;
    }

    @Override
    public void run() {
        fun();
    }

    public void fun() {
        //获取o1的monitor
        synchronized (o1) {
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //获取o2的monitor
            synchronized (o2) {

            }
        }
    }

}

public class DeadLock2 implements Runnable {

    private Object o1, o2;

    public DeadLock2(Object o1, Object o2) {
        this.o1 = o1;
        this.o2 = o2;
    }

    @Override
    public void run() {
        fun();
    }

    public void fun() {
        //获取o2的monitor
        synchronized (o2) {
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //获取o1的monitor
            synchronized (o1) {

            }
        }
    }

}

创建测试类

public class TestDeadLock {

    public static void main(String[] args) {
        Object lockObj1 = new Object();
        Object lockObj2 = new Object();
        //分别启动两个线程
        Thread thread1 = new Thread(new DeadLock1(lockObj1, lockObj2));
        thread1.start();
        Thread thread2 = new Thread(new DeadLock2(lockObj1, lockObj2));
        thread2.start();
    }

}

运行并打印堆栈信息:

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x0000000054a4d6b8 (object 0x00000000eb540e20, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x0000000054a4c218 (object 0x00000000eb540e30, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
	at zj.test.deadlock.DeadLock2.fun(DeadLock2.java:33)
	- waiting to lock <0x00000000eb540e20> (a java.lang.Object)
	- locked <0x00000000eb540e30> (a java.lang.Object)
	at zj.test.deadlock.DeadLock2.run(DeadLock2.java:19)
	at java.lang.Thread.run(Thread.java:745)
"Thread-0":
	at zj.test.deadlock.DeadLock1.fun(DeadLock1.java:33)
	- waiting to lock <0x00000000eb540e30> (a java.lang.Object)
	- locked <0x00000000eb540e20> (a java.lang.Object)
	at zj.test.deadlock.DeadLock1.run(DeadLock1.java:19)
	at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

线程0想要lock <0x00000000eb540e30>
线程1想要
lock <0x00000000eb540e20> 

双方都在等待对方释放锁




对于真正的死锁而言,虚拟机从锁的持有和请求情况就能判断出来,因此打印堆栈时虚拟机会自动给出死锁的提示


许多人把系统无响应的问题统称为死锁,这种称为是不恰当的

真正意义上的死锁是由于代码引入的错误而导致的死锁

 

要想从死锁中恢复临时也是唯一的规避办法是将系统重启,然后赶快去修改导致这个死锁的BUG

能否及时发现死锁,依赖于你的运气和你准备的测试用例的有效性

 tips:死锁的两个或多个线程是不消耗CPU的








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值