老規(guī)矩,先看例子
public class DeadLock {
public static void main(String[] args) {
Runnable r1 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("A") {
System.out.println("A線程持有了A鎖,等待B鎖");
synchronized ("B") {
System.out.println("A線程持有了A鎖和B鎖");
}
}
}
};
Runnable r2 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("B") {
System.out.println("B線程持有了B鎖,等待A鎖");
synchronized ("A") {
System.out.println("B線程持有了A鎖和B鎖");
}
}
}
};
Thread threadA = new Thread(r1);
Thread threadB = new Thread(r2);
threadA.start();
threadB.start();
}
}

image.png
我們發(fā)現(xiàn)程序沒有停止,因?yàn)閠hreadA一直在等待B鎖,B鎖卻被threadB搶走了,這時(shí)候threadA還沒有執(zhí)行完并不釋放A鎖,同理threadB在等待A鎖,兩個(gè)人就這樣一直等下去,形成了死鎖。
死鎖:多個(gè)線程互相持有對(duì)方需要的鎖對(duì)象,而不釋放自己的鎖。
解決
public class DeadLock {
//wait()等待,是Object中的方法,當(dāng)前線程釋放自己的所標(biāo)記,讓出CPU資源,使當(dāng)前線程進(jìn)入等待隊(duì)列
//notify()通知,是Object中的方法,喚醒等待隊(duì)列中的一個(gè)線程,使這個(gè)線程進(jìn)入鎖池。
//notifyAll()通知,喚醒等待隊(duì)列中的所有線程,并使這些線程進(jìn)入鎖池。
public static void main(String[] args) {
Runnable r1 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("A") {
System.out.println("A線程持有了A鎖,等待B鎖");
try {
"A".wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized ("B") {
System.out.println("A線程持有了A鎖和B鎖");
}
}
}
};
Runnable r2 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("B") {
System.out.println("B線程持有了B鎖,等待A鎖");
synchronized ("A") {
System.out.println("B線程持有了A鎖和B鎖");
//喚醒所有等待A鎖的線程
"A".notifyAll();
}
}
}
};
Thread threadA = new Thread(r1);
Thread threadB = new Thread(r2);
threadA.start();
threadB.start();
}
}
wait()等待,是Object中的方法,當(dāng)前線程釋放自己的所標(biāo)記,讓出CPU資源,使當(dāng)前線程進(jìn)入等待隊(duì)列
notify()通知,是Object中的方法,喚醒等待隊(duì)列中的一個(gè)線程,使這個(gè)線程進(jìn)入鎖池。
notifyAll()通知,喚醒等待隊(duì)列中的所有線程,并使這些線程進(jìn)入鎖池。