死鎖:程序不往下執行了,程序又沒有結束,就一直卡在哪里;
在使用synchronized的時候要避免死鎖,synchronized嵌套就可能會引發死鎖,需要嚴格的檢查代碼,排除死鎖發生的可能;
特意演示死鎖的案例:synchronized嵌套,使用多把同步鎖🔒
package android.java.thread15; /** * 定義死鎖任務 */ class DieLockThread extends Thread { /** * 此變量已經不是共享數據了,因為: * DieLockThread extends Thread * new DieLockThread().start(); * new DieLockThread().start(); * * 所以:Thread-0有自己的flag Thread-1也有自己的flag */ private boolean flag; public DieLockThread(boolean flag) { this.flag = flag; } @Override public void run() { int i = 0; int j = 0; if (flag) { while (true) { synchronized (Lock.LOCK1) // 使用第一把鎖🔒 { synchronized (Lock.LOCK2) // 使用第二把鎖🔒 { System.out.println("一一一一一一一一一一一一" + i++); } } } } else { while(true) { synchronized (Lock.LOCK2) // 使用第二把鎖🔒 { synchronized (Lock.LOCK1) // 使用第一把鎖🔒 { System.out.println("二二二二二二二二二二二二" + j++); } } } } } } /** * 定義兩把鎖🔒 */ class Lock { public final static Object LOCK1 = new Object(); public final static Object LOCK2 = new Object(); } public class DieLockDemo { public static void main(String[] args) { new DieLockThread(true).start(); new DieLockThread(false).start(); } }
死鎖結果,程序一直卡住不動了,不往下執行了:
分析死鎖🔒:
if (flag) { while (true) { // 第一步:CPU隨機性切換到:Thread-1 Thread-1正常往下走...... // 第六步:CPU隨機性切換到:Thread-1 ,然后判斷同步鎖 注意:此時的同步鎖🔒Lock == 第二把鎖🔒, 第二把鎖🔒是被Thread-1鎖定的,就造成了線程之間不和諧:死鎖 synchronized (Lock.LOCK1) // 使用第一把鎖🔒 { synchronized (Lock.LOCK2) // 使用第二把鎖🔒 { System.out.println("一一一一一一一一一一一一" + i++); // 第二步:CPU隨機性切換到:Thread-1 就在此時,CPU執行權沒有了, CPU去執行其他線程了 } } // 第四步: CPU隨機性切換到:Thread-1 Thread-1正常往下走完,並解鎖🔓 } } else { while(true) { // 第三步:CPU隨機切換到:Thread-0,然后判斷同步鎖 注意:此時的同步鎖🔒Lock == 第二把鎖🔒, 第二把鎖🔒是被Thread-1鎖定的,就造成了線程之間不和諧:死鎖 synchronized (Lock.LOCK2) // 使用第二把鎖🔒 { synchronized (Lock.LOCK1) // 使用第一把鎖🔒 { 第五步:CPU隨機性切換到:Thread-0 就在此時,CPU執行權沒有了, CPU去執行其他線程了 System.out.println("二二二二二二二二二二二二" + j++); } } } }
開發中,千萬不能出現死鎖;
出現死鎖的原因有:多線程並發/多個地方調用 + synchronized(多把鎖)