java线程死锁例子_java多线程中死锁情况的一个示例

1 packagecom.qust.demo.money;2

3 classA {4

5 public synchronized voidfoo(B b) {6 System.out.println(Thread.currentThread().getName() + " 进入A的foo");7 try{8 Thread.sleep(200);9 } catch(InterruptedException ex) {10 ex.printStackTrace();11 }12 System.out.println(Thread.currentThread().getName() + " 试图调用B的last");13 b.last();14 }15

16 public synchronized voidlast() {17 System.out.println("A的last()");18 }19 }20

21 classB {22

23 public synchronized voidbar(A a) {24 System.out.println(Thread.currentThread().getName() + " 进入B的bar");25 try{26 Thread.sleep(200);27 } catch(InterruptedException ex) {28 ex.printStackTrace();29 }30 System.out.println(Thread.currentThread().getName() + " 试图调用A的last");31 a.last();32 }33

34 public synchronized voidlast() {35 System.out.println("B的last()");36 }37 }38

39 public class DeadLock implementsRunnable {40

41 A a = newA();42 B b = newB();43

44 public voidinit() {45 Thread.currentThread().setName("主线程");46 System.out.println("进入主线程");47 a.foo(b);48 }49

50 public voidrun() {51 Thread.currentThread().setName("副线程");52 System.out.println("进入副线程");53 b.bar(a);54 }55

56 public static voidmain(String[] args) {57 DeadLock dl = newDeadLock();58 newThread(dl).start();59 dl.init();60 }61 }

下面是运行结果

1 进入主线程2 进入副线程3 主线程 进入A的foo4 副线程 进入B的bar5 副线程 试图调用A的last6 主线程 试图调用B的last

我们看到,正常情况下,最后还应该打印出“A的last()”和"B的last()",但是因为线程死锁的原因,所以程序一直在等待执行,没能正常的执行下去。

在上面的代码里面,为什么会出现死锁这种情况呢?我们来简单分析一下。

首先虽然副线程的start()是在主线程的init()之前,但是因为多线程开启也需要一段时间,所以我们可以看到,是主线程的init()方法执行在 前,然后在init()里面调用了a.foo()。A类和B类中的方法都是同步方法,因此,A的对象和B的对象都是同步锁。在进入A的foo()之前,线 程会对A加锁,然后线程睡眠200ms,这时候副线程调用B的bar(),同样的会对B加锁,然后睡眠200ms。这时候,主线程唤醒,试图调用B的 bar方法,因为是同步方法,所以需要对B加锁,但是这时候B已经被副线程锁住了,所以主线程就一直处于阻塞状态。当副线程唤醒的时候,试图调用A的同步 方法,同样需要对A加锁,但是这时候主线程持有A的锁,并处于阻塞状态,所以副线程也不能向下执行,大家都在等着对方释放锁,因此出现了我们上面说的死锁 的情况。

如果我们把A和B的last()的synchronized去掉,那么程序在调用last()之前就不需要对对象进行加锁,也就不会出现死锁的情况。

因为在工作中还没有遇到这种情况,所以只能拿这个实例程序讲解了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值