java 多线程 7 : 死锁

it2026-02-15  20

两个线程互相等待对方释放同步监视器就会发生死锁

public class A { public synchronized void foo(B b) { System.out.println("当前线程:" + Thread.currentThread().getName() + "进入A实例的foo方法"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("当前线程:" + Thread.currentThread().getName() + "企图调用B实例的last方法"); b.last(); } public synchronized void last() { System.out.println("进入到A的last方法"); } } public class B { public synchronized void bar(A a) { System.out.println("当前线程:" + Thread.currentThread().getName() + "进入B的bar方法"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("当前线程:" + Thread.currentThread().getName() + "企图调用A实例的last方法"); a.last(); } public synchronized void last(){ System.out.println("进入B的last方法内"); } } public class DeadLock implements Runnable{ A a = new A(); B b = new B(); public void init() { Thread.currentThread().setName("主线程"); a.foo(b); System.out.println("进入主线程之后"); } @Override public void run() { Thread.currentThread().setName("副线程"); b.bar(a); System.out.println("进入副线程之后"); } public static void main(String[] args) { DeadLock dl = new DeadLock(); new Thread(dl).start(); dl.init(); } }

 

结果分析:

副线程先执行 —— b调用bar() —— 进入bar方法前“副线程”对B对象加锁 —— 执行sleep,睡2s —— cpu切换执行到另一个线程

主线程开始执行 —— a调用foo() —— 进入foo方法前“主线程”对A对象加锁 —— 执行sleep,睡2s —— cpu切换执行到另一个线程(此时副线程醒了)

副线程醒了继续向下执行 —— 企图调用A实例的last同步方法 —— 但是此时主线程保持着对A对象的加锁,那么副线程就等待主线程对A的释放,等待......

主线程2s过后也醒了 ,继续向下执行 —— 企图调用B实例的last同步方法 —— 但是副线程仍然保持着对B对象的加锁,主线程等待副线程对B的释放,等待......

相互等待 , 就耗着了  , 死锁。

 

注意: Thread的suspend() 方法很容易导致死锁 , java不推荐使用该方法来暂停线程。

 

转载于:https://www.cnblogs.com/Uzai/p/9679001.html

最新回复(0)