2015-04-05 24 views
1

以下方法是SomeType类的方法 - 它用作其参数的类型。 行注释表示行#s。方法调用和同步块之间的“间隙” - 避免并发中的死锁

synchronized void someMethod(SomeType other) { // line 1 
           // line 2 
    synchronized (other) {  // line 3 
     //...do stuff   // line 4 
    } 
} 

块表示为“线4”具有的两个thisother一些其他同步方法调用,并且该代码是用于避免死锁。

但是 - 假设同时调用a.someMethod(b)b.someMethod(a),其中ab是不同的实例。

进一步假设b.someMethod(a)被调用后立即a.someMethod(b)是,他们都在行2--每个ab获得自己的锁,并等待对方的锁进行举起 。

这可能发生吗?

如果是这样 - 在哪个jdk实现?这看起来像取决于具体实现的东西,除非它明确地在jdk规范中。

TIA

+2

但'b'可以在*'a'进入第3行的块之前进入'someMethod()'*。每个线程都拥有顶级监视器并且处于死锁状态。 – chrylis 2015-04-05 20:54:22

+0

当然,看起来像是一个僵局。我见过的常用方法是始终以明确的顺序获取互斥锁。 – chrylis 2015-04-05 20:54:57

+0

@chrylis好的,我的错。 – 2015-04-05 20:56:03

回答

1

是的,你描述的死锁可能会发生。它发生的频率可能取决于线程代码的细节;现在,您很可能使用操作系统的本地线程,所以它更依赖于本机操作系统而不是JDK/JRE。尽管在大多数平台上可能会出现死锁,所以您应该在代码中防范它。

如果您认为该方法的争用会很低或者您不关心性能,则可以在静态成员或类本身上进行同步,而不是在对象上同步。如果您关心性能并认为争用会很大,那么您需要找出一种方法来确保监视器被锁定在相同的顺序,而不管调用方法的哪个对象以及哪个方法参数。