为何该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
相关产品推荐
相关产品推荐

