死鎖知識總結
阿新 • • 發佈:2021-01-03
1.概念
兩個或多個程序在執行的過程中,因為競爭資源而造成互相等待的現象
2.Demo
看下面的例子,對概念有個更加清晰的認識。
1 public class DeadLockDemo { 2 3 public static void main(String[] args) { 4 5 Object a = new Object(); 6 Object b = new Object(); 7 8 new Thread(new Runnable() { 9 10View Code@Override 11 public void run() { 12 synchronized (a) { 13 try { 14 System.out.println("Thread 1 started"); 15 System.out.println("Got the lock of Object a"); 16 Thread.sleep(1000);17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 System.out.println("Try to get the lock of Object b"); 21 synchronized (b) { 22 } 23 } 24 }25 }).start(); 26 27 new Thread(new Runnable() { 28 29 @Override 30 public void run() { 31 synchronized (b) { 32 try { 33 System.out.println("Thread 2 started"); 34 System.out.println("Got the lock of Object b"); 35 Thread.sleep(1000); 36 } catch (InterruptedException e) { 37 e.printStackTrace(); 38 } 39 System.out.println("Try to get the lock of Object a"); 40 synchronized (a) { 41 } 42 } 43 } 44 }).start(); 45 } 46 }
我們看程式碼,能立刻知道具體狀況。可是,實際專案裡,程式碼量巨大,執行時,我們如何排查呢?
3.死鎖排查
3.1 Jconsole
click 【Detect Deadlock】 button and then click【Deadlock】tab to check the Deadlock info.
3.2 jstack
jps查詢process id。然後根據id查詢stack資訊
中間省略。。。
至此,我們學到了如何排查死鎖的問題,那麼接下來,如何解決死鎖的問題呢?
4.死鎖產生的四個條件
①互斥量:鎖
②自己佔用一部分,同時想著佔取別人擁有的部分。
③不可蠻力搶佔對方的資源
④迴圈等待
拿最開始的程式碼的例子來說明。兩個執行緒各自持有一個資源,同時想要擁有對方的資源,但是不能蠻力搶佔,只能等到對方放開鎖之後,才能去持有,這樣就滿足了上訴的四個條件,所以,產生了死鎖。那麼我們,怎麼解決死鎖的問題呢?
5.解決死鎖
只要破壞上訴的任意一個條件即可。
1)使用定時的鎖,指定超時時間timeout
1 public class DeadLockDemo { 2 3 public static void main(String[] args) { 4 5 ReentrantLock lock1 = new ReentrantLock(); 6 ReentrantLock lock2 = new ReentrantLock(); 7 new Thread(new Runnable() { 8 9 @Override 10 public void run() { 11 lock1.tryLock(); 12 try { 13 System.out.println("Thread 1 started"); 14 System.out.println("Thread 1 Got the lock1"); 15 Thread.sleep(10000); 16 System.out.println("Thread 1 try to get the lock2"); 17 if(lock2.tryLock(2, TimeUnit.SECONDS)) { 18 try { 19 System.out.println("Thread1 : got lock1 and lock2 ..."); 20 } finally { 21 lock2.unlock(); 22 } 23 }; 24 } catch (InterruptedException e) { 25 e.printStackTrace(); 26 } finally { 27 lock1.unlock(); 28 } 29 } 30 }).start(); 31 32 new Thread(new Runnable() { 33 34 @Override 35 public void run() { 36 lock2.tryLock(); 37 try { 38 System.out.println("Thread 2 started"); 39 System.out.println("Thread 2 Got the lock2"); 40 Thread.sleep(10000); 41 System.out.println("Thread 2 try to get the lock1"); 42 if(lock1.tryLock(2, TimeUnit.SECONDS)) { 43 try { 44 System.out.println("Thread1 : got lock1 and lock2 ..."); 45 } finally { 46 lock1.unlock(); 47 } 48 }; 49 } catch (InterruptedException e) { 50 e.printStackTrace(); 51 } finally { 52 lock2.unlock(); 53 } 54 } 55 }).start(); 56 } 57 58 }View Code
2)按照相同順序來請求鎖
1 public class DeadLockDemo { 2 3 public static void main(String[] args) { 4 5 Object a = new Object(); 6 Object b = new Object(); 7 8 new Thread(new Runnable() { 9 10 @Override 11 public void run() { 12 synchronized (a) { 13 try { 14 System.out.println("Thread 1 started"); 15 System.out.println("Thread 1 Got the lock of Object a"); 16 Thread.sleep(1000); 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 synchronized (b) { 21 System.out.println("Thread 1 Got the lock of Object b"); 22 } 23 } 24 } 25 }).start(); 26 27 new Thread(new Runnable() { 28 29 @Override 30 public void run() { 31 synchronized (a) { 32 try { 33 System.out.println("Thread 2 started"); 34 System.out.println("Thread 2 Got the lock of Object a"); 35 Thread.sleep(1000); 36 } catch (InterruptedException e) { 37 e.printStackTrace(); 38 } 39 synchronized (b) { 40 System.out.println("Thread 2 Got the lock of Object a"); 41 } 42 } 43 } 44 }).start(); 45 }View Code