You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何该Java多线程程序中同一对象不会产生死锁?

为什么这段Java代码不会出现同一对象的死锁?

先把你的完整代码整理出来方便分析:

public class DeadLocks { 
    public static void main(String[] args) { 
        SyncObj so = new SyncObj(); 
        ThreadObj to = new ThreadObj(so); 
        ThreadObj1 to1 = new ThreadObj1(so); 
        to.start(); 
        to1.start(); 
    } 
} 

class SyncObj { 
    synchronized void foo() { 
        System.out.println("Foo Started"); 
        try { 
            Thread.sleep(1000); 
        } catch (InterruptedException e) { 
            e.printStackTrace(); 
        } 
        bar(); 
    } 

    synchronized void bar() { 
        System.out.println("bar s..."); 
    } 
}

要搞清楚为什么不会死锁,得先明白死锁的核心要求:至少两个线程,各自持有对方必须的锁,并且都不肯释放,形成循环等待。而你的代码完全不满足这个场景,原因有两点:

1. 所有同步方法共用同一把对象锁

你的SyncObj里的foo()和bar()都是synchronized实例方法,这意味着它们依赖的是同一个SyncObj对象(也就是代码里的so)的内置锁。不管哪个线程调用这两个方法,争夺的都是同一把锁——不存在“线程A持有锁1,线程B持有锁2,互相等着对方释放”的情况。

比如:

  • 如果线程to先拿到so的锁进入foo(),线程to1不管是调用foo()还是bar(),都会被阻塞,直到to释放锁。
  • 当to在foo()里调用bar()时,它已经持有so的锁了,根本不需要等待,直接就能进入bar()执行。

2. Java内置锁是可重入的

就算同一个线程多次请求同一把锁,Java也允许通过——这就是“可重入锁”的特性。比如上面说的,线程to已经持有so的锁,调用bar()时再次请求这把锁,不会被自己卡住,而是直接获得锁继续执行。这就避免了“自己等自己释放锁”的尴尬情况。

简单说,你的代码里只有一把锁,线程之间是排队抢这把锁,而不是互相攥着对方的锁不放,自然不会出现死锁。

内容的提问来源于stack exchange,提问作者Venkata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:40:18