死锁

描述

维基百科恰当地给出了“死锁”的定义:当两个以上的运算单元,双方都在等待对方停止执行,以获取系统资源,但是没有一方提前退出时,就称为死锁。JVM 中发生死锁之后,恢复的唯一方法是重新启动 JVM。

示例

下方是一个模拟两个线程之间死锁情况的示例代码:

package com.tier1app;
public class DeadLockSimulator {	
	public static Object Lock1 = new Object();
	public static Object Lock2 = new Object();

	   
	private static class FirstThread extends Thread {
	public void run() {
	synchronized (Lock1) {
	System.out.println("Thread 1: Holding lock 1...");
	try { Thread.sleep(10); } catch (Exception e) {}
	System.out.println("Thread 1: Waiting for lock 2...");
	synchronized (Lock2) {
	System.out.println("Thread 1: Holding lock 1 & 2...");
	}
	}
	}
	}   
	private static class SecondThread extends Thread {
	public void run() {
	synchronized (Lock2) {
	System.out.println("Thread 2: Holding lock 2...");
	try { Thread.sleep(10); } catch (Exception e) {}
	System.out.println("Thread 2: Waiting for lock 1...");
	synchronized (Lock1) {
	System.out.println("Thread 2: Holding lock 1 & 2...");
	}
	}
	}
	}
	public static void main(String args[]) {
		new FirstThread().start();
		new SecondThread().start();
	}
}

从上方的代码中,我们可以看到‘FirstThread’的执行路径:

1. 获取 Lock1 对象的锁定
2. 休眠 10 秒
3. 获取 Lock2 对象的锁定

以下是‘SecondThread’的执行路径:

1. 获取 Lock2 对象的锁定
2. 休眠 10 秒
3. 获取 Lock1 对象的锁定

如果您仔细阅读了上面的执行路径,FirstThread 在执行步骤 1 后将进入步骤 2。在步骤 2 时,SecondThread 则会执行其步骤 1。所以在 FirstThread 被唤醒并执行器步骤 3(即:尝试获取 Lock2)时,SecondThread 已经获取了 Lock2 的锁定。同样,SecondThread 执行其步骤 3(即:尝试获取 Lock1)时,FirstThread 已经获取了 Lock1 的锁定。这就会导致经典的死锁情形。从这种情况中恢复的唯一方法是重新启动 JVM。

上方代码中捕获的线程转储文件将会变成下面这样:

"Thread-1" prio=6 tid=0x0000000007319000 nid=0x7cd3c waiting for monitor entry [0x0000000008a3f000]
java.lang.Thread.State: BLOCKED (on object monitor)
	at com.tier1app.DeadLockSimulator$SecondThread.run(DeadLockSimulator.java:29)
	- waiting to lock 0x00000007ac3b1970 (a java.lang.Object)
	- locked 0x00000007ac3b1980 (a java.lang.Object)

Locked ownable synchronizers:
	- None

"Thread-0" prio=6 tid=0x0000000007318800 nid=0x7da14 waiting for monitor entry [0x000000000883f000]
java.lang.Thread.State: BLOCKED (on object monitor)
	at com.tier1app.DeadLockSimulator$FirstThread.run(DeadLockSimulator.java:16)
	- waiting to lock 0x00000007ac3b1980 (a java.lang.Object)
	- locked 0x00000007ac3b1970 (a java.lang.Object)

Locked ownable synchronizers:
	- None

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: