死锁是什么意思呢?打一个很简单的比喻吧。我(线程A)有一本书(锁a),你(线程B)有一支笔(锁b)。现在我想得到你的笔,而你想得到我的书。但是我必须得到你的笔做完一些事情后才能把书给你,而你也必须得到我的书后才能把你的笔给我。这样你和我一直为了得到对方的东西(实际上永远得不到)而一直阻塞。程序如下:
解决死锁的三个想法是:
一:以相同的顺序请求锁,上面的例子中,我先获得书,你先获取笔,程序可以设置,我们两个必须先获取到书才能请求笔,那么程序就不会发生死锁。当然这可能并不适用你的程序设计。
二:给书和笔在加上一个公共资源锁。即增加一个文具锁,只有获得文具锁后才能获取笔和书。这样也能避免死锁。
三:死锁检测,并打断所循环,退回某一个锁(退回锁时,注意还原线程状态),比如:A->B->C->D->A;即某一时刻发生死锁的情况是,A锁在请求B锁,B锁在请求C锁,C锁在请求D锁但是D锁在请求A锁。程序检测到死锁后,可以将B线程请求C锁的程序打断,并还原到B线程获取B锁之前(即B锁已经释放)。(死锁的检测又是一个技术活,大家可以百度相关技术)
总结:死锁的情况时很复杂的,上面的例子只是很简单的一种。具体的设计应当根据具体情况而定。
public class Test{
private static Object o1 = new Object();
private static Object o2 = new Object();
public static void main(String[] a) throws Exception{
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
test1();
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
test2();
}
});
thread1.start();
thread2.start();
}
private static void test1(){
synchronized (o1) {
try {
Thread.sleep(3000);
test2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void test2(){
synchronized (o2) {
try {
Thread.sleep(3000);
test1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}