Java线程死锁
来源:互联网 发布:gamemaker 源码 编辑:程序博客网 时间:2024/06/14 11:02
Java线程死锁
需要避免的与多任务处理有关的特殊错误类型是死锁(deadlock)。死锁发生在当两个线程对一对同步对象有循环依赖关系时。例如,假定一个线程进入了对象X的管程而另一个线程进入了对象Y的管程。如果X的线程试图调用Y的同步方法,它将像预料的一样被锁定。而Y的线程同样希望调用X的一些同步方法,线程永远等待,因为为到达X,必须释放自己的Y的锁定以使第一个线程可以完成。死锁是很难调试的错误,因为:
通常,它极少发生,只有到两线程的时间段刚好符合时才能发生。
它可能包含多于两个的线程和同步对象(也就是说,死锁在比刚讲述的例子有更多复杂的事件序列的时候可以发生)。
为充分理解死锁,观察它的行为是很有用的。下面的例子生成了两个类,A和B,分别有foo( )和bar( )方法。这两种方法在调用其他类的方法前有一个短暂的停顿。主类,名为Deadlock,创建了A和B的实例,然后启动第二个线程去设置死锁环境。foo( )和bar( )方法使用sleep( )强迫死锁现象发生。
运行程序后,输出如下:
因为程序死锁,你需要按CTRL-C来结束程序。在PC机上按CTRL-BREAK(或在Solaris下按CTRL-)你可以看到全线程和管程缓冲堆。你会看到RacingThread在等待管程a时占用管程b,同时,MainThread占用a等待b。该程序永远都不会结束。像该例阐明的,你的多线程程序经常被锁定,死锁是你首先应检查的问题。
需要避免的与多任务处理有关的特殊错误类型是死锁(deadlock)。死锁发生在当两个线程对一对同步对象有循环依赖关系时。例如,假定一个线程进入了对象X的管程而另一个线程进入了对象Y的管程。如果X的线程试图调用Y的同步方法,它将像预料的一样被锁定。而Y的线程同样希望调用X的一些同步方法,线程永远等待,因为为到达X,必须释放自己的Y的锁定以使第一个线程可以完成。死锁是很难调试的错误,因为:
通常,它极少发生,只有到两线程的时间段刚好符合时才能发生。
它可能包含多于两个的线程和同步对象(也就是说,死锁在比刚讲述的例子有更多复杂的事件序列的时候可以发生)。
为充分理解死锁,观察它的行为是很有用的。下面的例子生成了两个类,A和B,分别有foo( )和bar( )方法。这两种方法在调用其他类的方法前有一个短暂的停顿。主类,名为Deadlock,创建了A和B的实例,然后启动第二个线程去设置死锁环境。foo( )和bar( )方法使用sleep( )强迫死锁现象发生。
/*@(#)A.java 2017-4-17 * Copy Right 2017 Bank of Communications Co.Ltd. * All Copyright Reserved *//** * TODO Document A * <p> * @version 1.0.0,2017-4-17 * @author Caven * @since 1.0.0 */public class A {synchronized void foo(B b) { String name = Thread.currentThread().getName(); System.out.println(name + " entered A.foo"); try { Thread.sleep(1000); } catch(Exception e) { System.out.println("A Interrupted"); } System.out.println(name + " trying to call B.last()"); b.last(); } synchronized void last() { System.out.println("Inside A.last"); }}class B { synchronized void bar(A a) { String name = Thread.currentThread().getName(); System.out.println(name + " entered B.bar"); try { Thread.sleep(1000); } catch(Exception e) { System.out.println("B Interrupted"); } System.out.println(name + " trying to call A.last()"); a.last(); } synchronized void last() { System.out.println("Inside A.last"); }}class Deadlock implements Runnable { A a = new A(); B b = new B(); Deadlock() { Thread.currentThread().setName("MainThread"); Thread t = new Thread(this, "RacingThread"); t.start(); a.foo(b); // get lock on a in this thread. System.out.println("Back in main thread"); } public void run() { b.bar(a); // get lock on b in other thread. System.out.println("Back in other thread"); } public static void main(String args[]) { new Deadlock(); }}
运行程序后,输出如下:
MainThread entered A.fooRacingThread entered B.barRacingThread trying to call A.last()MainThread trying to call B.last()
因为程序死锁,你需要按CTRL-C来结束程序。在PC机上按CTRL-BREAK(或在Solaris下按CTRL-)你可以看到全线程和管程缓冲堆。你会看到RacingThread在等待管程a时占用管程b,同时,MainThread占用a等待b。该程序永远都不会结束。像该例阐明的,你的多线程程序经常被锁定,死锁是你首先应检查的问题。
1 0
- java线程死锁例子
- java模拟线程死锁
- java线程 死锁实例
- java 线程死锁
- Java多线程:线程死锁
- java 线程死锁模拟
- java线程死锁程序
- Java-线程$死锁
- java线程死锁
- Java编写线程死锁
- java线程死锁
- java 查看线程死锁
- java 线程死锁
- java线程死锁实例
- Java线程死锁
- java 线程死锁
- java线程死锁问题
- Java 实现线程死锁
- Damageable.cs
- 系统相关
- hdu3726:Graph and Queries(treap+启发式合并+离线)
- gdb操作实例
- 数据库
- Java线程死锁
- 幺半群
- poj 3667 线段树(区间合并)
- JQuery实现移动9宫格图片自由切换移动
- Activity之API指南
- 浅析exit()和atexit()函数
- c++控制命令行光标位置函数
- 动态规划练习一—26、30滑雪
- linux初级学习之设备的访问 学习笔记14