Java中死锁的原理实战分析

网友投稿 240 2022-12-29


Java中死锁的原理实战分析

本文实例讲述了java中死锁的原理。分享给大家供大家参考,具体如下:

一 点睛

当两个线程相互等待对方释放同步监视器时就会发生死锁,Java虚拟机没有监测、也没有采用措施来处理死锁情况,所以多线程编程时应该采取措施避免死锁的出现。

一旦出现死锁,整个程序既不会发生任何异常,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。

二 代码

class A

{

public synchronized void foo( B b )

{

System.out.println("当前线程名: " + Thread.currentThread().getName()

+ " 进入了A实例的foo()方法" ); // ①

try

{

Thread.sleep(200);

}

catch (InterruptedException ex)

{

ex.printStackTrace();

}

System.out.println("当前线程名: " + Thread.currentThread().getName()

+ " 企图调用B实例的last()方法"); // ③

b.last();

}

public synchronized void last()

{

System.out.println("进入了A类的last()方法内部");

}

}

class B

{

public synhttp://chronized void bar( A a )

{

System.out.println("当前线程名: " + Thread.currentThread().getName()

+ " 进入了B实例的bar()方法" ); // ②

try

{

Thread.sleep(200);

}

catch (InterruptedException ex)

{

ex.printStackTrace();

}

System.out.println("当前线程名: " + Thread.currentThread().getName()

+ " 企图调用A实例的last()方法"); // ④

a.last();

}

public synchronized void last()

{

System.out.println("进入了B类的last()方法内部");

}

}

public class DeadLock implements Runnable

{

A a = new A();

B b = new B();

public void init()

{

Thread.currentThread().setName("主线程");

// 调用a对象的foo方法

a.foo(b);

System.out.println("进入了主线程之后");

}

public void run()

{

Thread.currentThread().setName("副线程");

// 调用b对象的bar方法

b.bar(a);

System.out.println("进入了副线程之后");

}

public static void main(String[] args)

{

DeadLock dl = new DeadLock();

// 以dl为target启动新线程

new Thread(dl).start();

// 调用init()方法

dl.init();

}

}

三 运行结果

当前线程名: 主线程 进入了A实例的foo()方法

当前线程名: 副线程 进入了B实例的bar()方法

当前线程名: 主线程 企图调用B实例的last()方法

当前线程名: 副线程 企图调用A实例的last()方法

四 说明

从运行结果来看,程序无法向下执行,也不会抛出任何异常,就一直“僵持”者。

上面代码中的A对象和B对象的方法都是同步方法,也就是A对象和B对象都是同步锁。

程序中有两个线程执行,一个线程的线程执行体是DeadLock类的run()方法,另外一个是DeadLock的init()方法(主线程调用init()方法)。其中run()方法让B对象调用bar()方法,而init()方法让A对象调用foo()方法。

程序运行的流程如下:

1 init()方法先执行,调用A对象的foo()方法,进入foo()方法之前,该线程对A对象加锁,进入foo()方法后,打印一下,然后暂停执行200ms

2 CPU切换到另外一个线程,让B对象执行bar方法,进入bar()方法之前,该线程对B对象加锁,进入bar()方法后,打印一下,然后暂停执行200ms

3 主线程先醒过来,继续向下执行,当调用B对象的last方法时,会被阻塞,因为此时必须对B对象进行加锁,但此时副线程正保持B对象的锁,所以此时主线程会一直等待。

4 副线程会醒过来,会继续往下执行,当调用A对象的last方法时,会被阻塞,因为此时必须对A对象加锁,但此时主线程正保持A对象的锁,所以此时副线程会一直等待。

5 两个线程互相等待对方先释放,所以出现了死锁。

更多java相关内容感兴趣的读者可查看本站专题:《Java进程与线程操作技巧总结》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:商城商品模块接口测试工具(商城商品模块接口测试工具下载)
下一篇:系统接口设计教程电子版(管理系统接口设计)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~