鎖是個非常有用的工具,運用場景非常多,因為它使用起來非常簡單,而且易於理解。但同時它也會帶來一些困擾,那就是可能會引起死鎖,一旦產生死鎖,就會造成系統功能不可用。讓我們先來看一段代碼,這段代碼會引起死鎖,使線程t1和線程t2互相等待對方釋放鎖。
class DeadLockDemo { private static String A = "A"; private static String B = "B"; public static void main(String[] args) { new DeadLockDemo().deadLock(); } private void deadLock() { Thread t1 = new Thread(new Runnable() { @Override public void run() { synchronized (A) { try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (B) { System.out.println("1"); } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { synchronized (B) { synchronized (A) { System.out.println("2"); } } } }); t1.start(); t2.start(); } }
這段代碼只是演示死鎖的場景,在現實中你可能不會寫出這樣的代碼。但是,在一些更為復雜的場景中,你可能會遇到這樣的問題,比如t1拿到鎖之后,因為一些異常情況沒有釋放鎖(死循環)。又或者是t1拿到一個數據庫鎖,釋放鎖的時候拋出了異常,沒釋放掉。
一旦出現死鎖,業務是可感知的,因為不能繼續提供服務了,那么只能通過dump線程查看到底是哪個線程出現了問題,以下線程信息告訴我們是"b1_2死鎖"類的第37行和第26行引起的死鎖。
參考:
1.https://blog.csdn.net/qq_36317804/article/details/89522433
2.Java並發編程藝術1.2