JAVA多线程——死锁分析

来源:互联网 发布:windows loader 3.1.0 编辑:程序博客网 时间:2024/05/06 15:55

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

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


简单的死锁例子

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

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
原创粉丝点击