首先看下面一个例子,
package aaa;
public class test {
public static void main(String[] args) {
Object obj = new Object();
Object obj1 = new Object();
LockThread diedLock = new LockThread(obj, obj1);
LockThread1 diedLock1 = new LockThread1(obj, obj1);
diedLock.start();
diedLock1.start();
}
}
class LockThread extends Thread {
private Object obj;
private Object obj1;
public LockThread(Object obj, Object obj1) {
this.obj = obj;
this.obj1 = obj1;
}
@Override
public void run() {
synchronized (obj) {
try {
Thread.sleep(500);
synchronized (obj1) {
System.out.println("执行不到这一步,因为LockThread1类中已经将obj1锁住,");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class LockThread1 extends Thread {
private Object obj;
private Object obj1;
public LockThread1(Object obj, Object obj1) {
this.obj = obj;
this.obj1 = obj1;
}
@Override
public void run() {
synchronized (obj1) {
try {
Thread.sleep(500);
synchronized (obj) {
System.out.println("执行不到这一步,因为LockThread类中已经将obj锁住,他们都在等待对方释放资源");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
其中obj 和obj1 是两个共享变量,调用LockThread 执行run方法的时 首先将obj 对象锁住(synchronized),然后sleep 0.5秒,此时程序将调用LockThread1 类的run方法,将obj1对象锁住(synchronized),然后sleep 0.5秒,此时LockThread的run方法睡醒了,要去锁obj1对象,但是此时obj1对象已经被LockThread1 类锁住,要等LockThread1 类释放了对obj1对象的锁之后才可以继续执行LockThread类的run方法,现在LockThread1 类睡醒了,需要对obj对象加锁,但是此时obj对象已经被LockThread类的run方法锁,所以LockThread1 类需要LockThread类释放了对obj对象的锁才可以继续往下执行。 但是此时就会发现LockThread类在等待LockThread1 释放obj1的锁,LockThread1 又在等待LockThread释放obj的锁,他们互相在等待,但是又互相不释放,程序就会静止在这里所以就产生了死锁。 (因为多线程是CPU快速切换的,所以这里的流程讲解都是主观判断)