本篇楼主接着上篇多线程的安全问题继续讨论多线程的死锁问题。
我们可以构造这样一种场景:传统(理想)情况下,楼主吃饭必须用两支筷子,而楼主老板(美国人)吃饭必须要用一刀,一叉;现在,楼主手上有一支筷子和一把刀,老板手上有一支筷子和一把叉;当我们都在互相等待对方把餐具给我们时,出现相互等待的现象,都吃不了饭,从而形成死锁。
所以上篇所说到的解决多线程同步的安全问题又衍生出了:如果出现同步嵌套,就容易产生死锁的问题。上面的场景我们先用代码来实现看一看。
构建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工程。