死锁知识总结

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

 

posted @ 2021-01-03 15:44  Mr.袋鼠  阅读(107)  评论(0编辑  收藏  举报