Java中的死鎖和活鎖都是并發(fā)編程中的常見(jiàn)問(wèn)題,它們都是由于線程間互相等待對(duì)方釋放資源而導(dǎo)致的程序無(wú)限阻塞的問(wèn)題。不過(guò),死鎖是兩個(gè)或多個(gè)線程互相等待對(duì)方持有的資源而無(wú)法繼續(xù)執(zhí)行下去,活鎖則是線程一直重試某個(gè)操作,但由于某些原因一直失敗而無(wú)法終止。
public class DeadlockExample { static Object lock1 = new Object(); static Object lock2 = new Object(); public static void main(String[] args) { Thread thread1 = new Thread(() ->{ synchronized (lock1) { System.out.println("Thread 1 acquired lock 1"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock2) { System.out.println("Thread 1 acquired lock 2"); } } }); Thread thread2 = new Thread(() ->{ synchronized (lock2) { System.out.println("Thread 2 acquired lock 2"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock1) { System.out.println("Thread 2 acquired lock 1"); } } }); thread1.start(); thread2.start(); } }
上面是一個(gè)經(jīng)典的死鎖示例,兩個(gè)線程相互占用對(duì)方需要的鎖,然后進(jìn)入無(wú)限等待狀態(tài)。如果在實(shí)際應(yīng)用中發(fā)生了這種情況,程序就會(huì)一直阻塞下去,導(dǎo)致資源浪費(fèi)和性能下降。
public class LivelockExample { static Integer count = 0; public static void main(String[] args) { Thread thread1 = new Thread(() ->{ while (count< 5) { count++; System.out.println("Thread 1 increments count to " + count); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread thread2 = new Thread(() ->{ while (count >0) { count--; System.out.println("Thread 2 decrements count to " + count); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread1.start(); thread2.start(); } }
這是一個(gè)簡(jiǎn)單的活鎖示例,兩個(gè)線程都在不停地嘗試修改一個(gè)共享變量count,由于兩個(gè)線程互相干擾,它們一直無(wú)法正確地完成操作,最終導(dǎo)致程序一直運(yùn)行下去。這種情況很類似于兩個(gè)人在走廊上面試讓對(duì)方讓路,但彼此都不愿意離開(kāi),最終導(dǎo)致雙方都無(wú)法通過(guò)。