1. 程式人生 > 實用技巧 >死鎖知識總結

死鎖知識總結

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             
10
@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 }
View Code

我們看程式碼,能立刻知道具體狀況。可是,實際專案裡,程式碼量巨大,執行時,我們如何排查呢?

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