概念,AB線程,A持有a鎖B持有b鎖,A在等待b鎖,而B在等待a鎖
發生場景之一:同步嵌套
簡單的嵌套造成死鎖的Demo:
class Lock implements Runnable{
private boolean flag;
public Lock(boolean flag){
this.flag = flag;
}
@Override
public void run() {
if(flag){
while(true){
synchronized (LockObj.obj1) {
System.out.println(Thread.currentThread().getName()+" if...");
synchronized (LockObj.obj2) {
System.out.println(Thread.currentThread().getName()+" if...");
}
}
}
}else{
while(true){
synchronized (LockObj.obj2) {
System.out.println(Thread.currentThread().getName()+" else...");
synchronized (LockObj.obj1) {
System.out.println(Thread.currentThread().getName()+" else...");
}
}
}
}
}
public synchronized void show(){
System.out.println(Thread.currentThread().getName()+"show...");
}
}
class LockObj{
public static final Object obj1 = new Object();
public static final Object obj2 = new Object();
}
class Test{
public static void main(String[] args) {
Lock l1 = new Lock(false);
Lock l2 = new Lock(true);
Thread t1 = new Thread(l1);
Thread t2 = new Thread(l2);
t1.start();
t2.start();
}
}
這個demo我測試過了,沒問題的,絕壁死鎖。簡單分析一下,線程t1因爲flag爲false所以永遠走esle分支,相反的t2永遠走if分支,當main線程運行到t2.start();之後,兩個線程開啓,假定t2先拿到cpu的執行權,走if分支拿到obj1鎖,這時候有可能t1也拿到cpu的執行權拿到obj2的鎖,再如果t2繼續走想拿obj2鎖,但此時obj2鎖在t1手裏,而t2也想拿obj1,這樣都相互想拿對方的鎖,就僵持不下造成死鎖,加一個while(true)的原因是讓他一定出現死鎖,不然有時候試好多次,死鎖的現象不明顯就蛋碎了。