Q:什么是死锁?
A:在多线程中,由于在同步中嵌套同步,可能会造成两个线程各占一把锁,双方都需要对方的锁才能继续执行下去,但在未得到对方的锁之前,双方都不能交出自己的锁,造成了死锁。
死锁代码
DeadLock.java
public class DeadLock {
public static void main(String[] args) {
MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
myThread1.setFlag(0);
myThread2.setFlag(1);
Thread t1 = new Thread(myThread1);
Thread t2 = new Thread(myThread2);
// 根据参数设置可知t1线程使用了obj1的锁,需要obj2的锁才能执行。而obj2被t2线程使用,t2需要obj1的锁才能完成执行释放obj1的锁。
// 双方各占一把锁,都需要对方的锁才能继续完成执行而释放对方需要的锁,却都无法得到对方的锁而不能完成执行,导致双方都无法继续执行下去,造成了死锁。
t1.start();
t2.start();
}
}
class MyThread implements Runnable{
private int flag;
public static Object obj1 = new Object(), obj2 = new Object();
public void setFlag(int flag) {
this.flag = flag;
}
@Override
public void run() {
if(flag == 0) {
// obj1的锁正在使用
synchronized(obj1) {
System.out.println("flag = " + flag);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 此处需要obj2的锁才能执行,但obj2的锁正在使用
synchronized(obj2){
System.out.println("flag = " + flag + " was finished");
}
}
}
if(flag == 1) {
// obj2的锁正在使用
synchronized(obj2) {
System.out.println("flag = " + flag);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 此处需要obj1的锁才能执行,但obj1的锁正在使用
synchronized(obj1){
System.out.println("flag = " + flag + " was finished");
}
}
}
}
}
运行结果
一直在运行,无法结束。
死锁会导致线程阻塞,程序不能正常运行,所以应避免在同步中嵌套同步,防止死锁发生。