线程技术之死锁问题

 我们知道,使用 synchronized 关键字可以有效的解决线程同步问题,但是如果不恰当的使用 synchronized 关键字的话也会出问题,即我们所说的死锁。死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

下面写一个死锁的例子加深理解。先看程序,再来分析一下死锁产生的原因:

public class DeadLock {      public static void main(String[] args) {         Business business = new Business1();         //开启一个线程执行Business类中的functionA方法         new Thread(new Runnable() {                          @Override             public void run() {                 while(true) {                     business.functionA();                 }             }         }).start();                  //开启另一个线程执行Business类中的functionB方法         new Thread(new Runnable() {                          @Override             public void run() {                 while(true) {                     business.functionB();                 }             }         }).start();     }  }  class Business { //定义两个锁,两个方法     //定义两个锁     public static final Object lock_a = new Object();     public static final Object lock_b = new Object();             public void functionA() {         synchronized(lock_a) {             System.out.println("---ThreadA---lock_a---");             synchronized(lock_b) {                 System.out.println("---ThreadA---lock_b---");             }         }     }          public void functionB() {         synchronized(lock_b) {             System.out.println("---ThreadB---lock_b---");             synchronized(lock_a) {                 System.out.println("---ThreadB---lock_a---");             }         }     } }

程序结构很清晰,没什么难度,先看一下程序的执行结果:

---ThreadA---lock_a---
---ThreadA---lock_b---
---ThreadA---lock_a---
---ThreadA---lock_b---
---ThreadA---lock_a---
---ThreadA---lock_b---
---ThreadA---lock_a---
---ThreadB---lock_b---

从执行结果来看,线程A跑着跑着,当线程B一跑,啪叽一下就挂了~我们来分析一下原因:从上面的代码中可以看出,定义了一个类Business,该类中维护了两个锁和两个方法,每个方法都是 synchronized 连环套,并且使用的是不同的锁。好了,现在 main 方法中开启两个线程A和B,分别执行Business类中的两个方法。A优先执行,跑的很爽,当B线程也开始执行的时候,问题来了,从执行结果的最后两行来看,A线程进入了 functionA 方法中的第一个 synchronized,拿到了 lock_a 锁,B线程进入了 functionB 中的第一个 `synchronized,拿到了 lock_b 锁,并且两者的锁都还没释放。

接下来就是关键了:A线程进入第二个 synchronized 的时候,发现 lock_b 正在被B占用,那没办法,它只好被阻塞,等呗~同样地,B线程进入第二个 synchronized&

50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信