背景
这个话题是源自笔者以前跟人的一次技术讨论,“你是怎么发现死锁的并且是如何预防、如何解决的?”以前听到的这个问题的时候,虽然脑海里也有一些思路,但是都是不够系统化的东西。直到最近亲身经历一次死锁,才做了这么一次集中的思路整理,撰录以下文字。希望对同样问题的同学有所帮助。
死锁定义
首先我们先来看看死锁的定义:“死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。”那么我们换一个更加规范的定义:“集合中的每一个进程都在等待只能由本集合中的其他进程才能引发的事件,那么该组进程是死锁的。”
竞争的资源可以是:锁、网络连接、通知事件,磁盘、带宽,以及一切可以被称作“资源”的东西。
举个栗子
上面的内容可能有些抽象,因此我们举个例子来描述,如果此时有一个线程A,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程B,按照先锁b再锁a的顺序获得锁。如下图所示:

死锁
我们用一段代码来模拟上述过程:
public static void main(String[] args) {
final Object a = new Object();
final Object b = new Object();
Thread threadA = new Thread(new Runnable() {
public void run() {
synchronized (a) {
try {
System.out.println("now i in threadA-locka");
Thread.sleep(1000l);
synchronized (b) {
System.out.println("now i in threadA-lockb");
}
} catch (Exception e) {
// ignore
}
}
}
});
Thread threadB = new Thread(new Runnable() {
public void run() {
synchronized (b) {
try {
System.out.println("now i in threadB-lockb");
Thread.sleep(1000l);
synchronized (a) {
System.out.println("now i in threadB-locka");
}
} catch (Exception e) {
// ignore
}
}
}
});
threadA.start();
threadB.start();
}
程序执行结果如下:

程序执行结果
很明显,程序执行停滞了。
死锁检测
在这里,我将介绍两种死锁检测工具