首页 > 代码库 > 多线程中的死锁举例与分析(转)
多线程中的死锁举例与分析(转)
1. 一个特殊构造的程序
考虑下面这个专门为说明多线程中的死锁现象而构造的程序:
import java.util.LinkedList;public class Stack { public static void main(String[] args) { final Stack stack = new Stack(); new Thread("push") { @Override public void run() { for (int i = 0; i < 100; i++) { try { Thread.sleep(10);//to make the deadlock occur } catch (InterruptedException e) { } stack.push("object " + i); } } }.start(); new Thread("pop") { @Override public void run() { for (int i = 0; i < 100; i++) { try { System.out.println(stack.pop()); } catch (Exception e) { } } } }.start(); } LinkedList<Object> list = new LinkedList<Object>(); public synchronized void push(Object x) { System.out.println("begin to push " + x); synchronized (list) { list.addLast(x); notify(); } System.out.println("end to push " + x); } public synchronized Object pop() throws Exception { System.out.println("begin to pop"); synchronized (list) { if (list.size() <= 0) { wait(); } return list.removeLast(); } } }
该程序构造了一个 Stack,启动了两个线程。一个线程向 Stack 中添加数据,另外一个线程从 Stack 中取出数据并打印。
但是运行程序后就会发现程序输出:
begin to popbegin to push object 0
后,在再也没有后续输出了。
2. Dump 并分析线程状态
启动 jvisualvm 查看该程序线程的状态,将其 Dump,就可以得到以下线程堆栈信息:
"pop" prio=6 tid=0x00c00000 nid=0x2b0 in Object.wait() [0x00f9f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x27f65648> (a loggerlock.Stack) at java.lang.Object.wait(Object.java:485) at loggerlock.Stack.pop(Stack.java:49) - locked <0x27f65658> (a java.util.LinkedList) - locked <0x27f65648> (a loggerlock.Stack) at loggerlock.Stack$2.run(Stack.java:26) Locked ownable synchronizers: - None"push" prio=6 tid=0x00bfec00 nid=0x14c8 waiting for monitor entry [0x00f4f000] java.lang.Thread.State: BLOCKED (on object monitor) at loggerlock.Stack.push(Stack.java:39) - waiting to lock <0x27f65658> (a java.util.LinkedList) - locked <0x27f65648> (a loggerlock.Stack) at loggerlock.Stack$1.run(Stack.java:16) Locked ownable synchronizers: - None
可以看到,pop 线程正在运行 wait(); 语句,处于 WAITING 状态,同时,该线程锁住了 list 和 stack 对象。
push 线程处于 BLOCKED 状态,等待其他线程释放 list 对象。
3. 运行过程及死锁原因分析
步骤 | 主程序 | pop 线程 | push 线程 |
1 | 启动 | ||
2 | 创建 stack 对象 | ||
3 | 创建 list 对象 | ||
4 | 启动 | ||
5 | 启动 | ||
6 | sleep 10ms | ||
7 | 调用 stack.pop() | ||
8 | 锁住 stack 对象 | ||
9 | 打印 "begin to pop" | ||
10 | 锁住 list 对象 | ||
11 | 调用 stack.wait() | ||
12 | 锁住 stack 对象 | ||
13 | 打印 "begin to push 0" | ||
14 | 企图锁住 list 对象 | ||
15 | 进入死锁状态 |
http://www.educity.cn/it/sun/201004191051041573.htm
多线程中的死锁举例与分析(转)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。