本篇学习什么是多线程死锁,怎么避免线程死锁。这个问题,在面试了应该也经常被提到。关于,线程死锁,有这么一个故事。一个饭桌上,有丰盛的菜肴,圆桌围着几个哲学家,问题来了,每个哲学家只有一根筷子。假如必须得到两根筷子,才能享受菜肴。哲学家们都想从身边的人手里拿到另外一根筷子,结果是谁都说服不了谁,都没有拿到一双筷子,结果哲学家们都饿死了。这个拿不到一双筷子,在电脑里面的线程就是死锁问题。
多线程死锁,就是在多线程环境中,如果使用了同步代码块嵌套,而且使用同一个锁对象,就很容易发生线程死锁。如果要避免线程死锁,唯一的办法就是尽量不去使用代码块同步嵌套。下面举例一个同步嵌套,造成都拿不到一对筷子的线程死锁问题。
package thread;
public class Demo5_DeadLock {
public static String s1 = "筷子-左";
public static String s2 = "筷子-右";
public static void main(String[] args) {
new Thread() {
public void run() {
while(true) {
synchronized(s1) {
System.out.println(getName() +"...拿到" + s1 + "等待" + s2);
synchronized(s2) {
System.out.println(getName() +"...拿到" + s2 + "开吃");
}
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
synchronized(s2) {
System.out.println(getName() +"...拿到" + s2 + "等待" + s1);
synchronized(s1) {
System.out.println(getName() +"...拿到" + s1 + "开吃");
}
}
}
}
}.start();
}
}
运行后,最后两行输出如下,就出现死锁,IDE运行进程没有结束,但是没有执行其他打印代码。
Thread-1...拿到筷子-左开吃
Thread-1...拿到筷子-右等待筷子-左
Thread-0...拿到筷子-左等待筷子-右