多线程之死锁产生

本篇楼主接着上篇多线程的安全问题继续讨论多线程的死锁问题。

我们可以构造这样一种场景:传统(理想)情况下,楼主吃饭必须用两支筷子,而楼主老板(美国人)吃饭必须要用一刀,一叉;现在,楼主手上有一支筷子和一把刀,老板手上有一支筷子和一把叉;当我们都在互相等待对方把餐具给我们时,出现相互等待的现象,都吃不了饭,从而形成死锁。

所以上篇所说到的解决多线程同步的安全问题又衍生出了:如果出现同步嵌套,就容易产生死锁的问题。上面的场景我们先用代码来实现看一看。

构建MyLock类,创建楼主,老板两个锁对象:

1 package com.jon.dielock;
2 
3 public class MyLock{
4     //创建2把所对象
5     public static final Object objA = new Object();
6     public static final Object objB = new Object();
7 }

创建DieLock类集成Thread,构建死锁场景(同步嵌套):

 1 package com.jon.dielock;
 2 
 3 public class DieLock extends Thread {
 4     private boolean flag;//线程创建时给定不同的标记以表示不同的人
 5     public DieLock(boolean flag){
 6         this.flag = flag;
 7     }
 8     @Override
 9     public void run() {
10         if(flag){
11             synchronized(MyLock.objA){
12                 System.out.println("if objA");
13                 synchronized(MyLock.objB){
14                     System.out.println("if objB");
15                 }    
16             }            
17         }else{
18             synchronized(MyLock.objB){
19                 System.out.println("else objB");
20                 synchronized(MyLock.objA){
21                     System.out.println("else objA");
22                 }    
23             }            
24         }
25     }
26 }

创建测试类TestDieLock:

 1 package com.jon.dielock;
 2 
 3 public class TestDieLock {
 4 
 5     public static void main(String[] args) {
 6         DieLock dl1 = new DieLock(true);
 7         DieLock dl2 = new DieLock(false);
 8         
 9         dl1.start();
10         dl2.start();
11     }
12 
13 }

我们运行看输出结果:

1 else objB
2 if objA

很明显if和else都没执行完,理想情况下应全部输出。

下面还是习惯性的以图来说明(假设线程dl2先抢到CPU的执行权):

此场景形成死锁的解决方案楼主在下一篇将会具体说明。本文用到的相关代码地址:https://github.com/LJunChina/JavaResource的DieLock工程。

 

posted @ 2017-03-08 21:47  有BUG  阅读(388)  评论(0编辑  收藏  举报