2015-11-20 98 views
0

它在this question静态和非静态同步

有同步的静态方法和sync'ed非静态方法

好之间没有联系,这是非常简单的说,但如果非静态方法中的代码调用静态方法会怎么样?此线程是否同时保持静态(与类关联)和非静态(与类的实例关联)监视器?

+5

一般来说,当你从一个“同步”模块输入另一个模块(在不同的对象上同步)时,你必须获得两个显示器。(如果代码的另一部分试图以相反的顺序获取相同的两台显示器,那么会出现死锁。) – biziclop

回答

2

该线程是否同时保持静态(与类关联)和 非静态(与类的实例关联)监视器?

是的,这是因为,

按照Java Language Specification 8.4.3.6

对于类(静态) 方法中,使用具有用于该方法的 类的Class对象相关联的显示器。对于实例方法,使用与此(调用方法的对象)关联的监视器。

而后所有的2个监视器将单独定义。

+0

您[引用JLS](http://docs.oracle.com/javase/specs/ jls/se7/html/jls-8.html#jls-8.4.3.6)。你当然应该这样说,既要进行适当的归因,以避免剽窃费用,并且要给你的答案增加分量,你应该使用报价格式来表示引用的文本。 – EJP

+0

照顾你的评论,谢谢你的反馈。 – Dish

+0

'根据Java语言规范8.4.3.6'没有引用文本,不应该如此格式化。 – EJP

1

没有“静态同步”或“非静态同步”之类的东西。这些想法隐藏了真正发生的事情。

此:

class Foobar { 
    static synchronized void mumble() { ... } 
} 

只是为了写这一条捷径:

class Foobar { 
    static void mumble() { 
     synchronized(Foobar.class) { 
      ... 
     } 
    } 
} 

而且这样的:

class Foobar { 
    synchronized void grumble() { ... } 
} 

只是为了写这一条捷径:

class Foobar { 
    void grumble() { 
     synchronized(this) { 
      ... 
     } 
    } 
} 

谈论“静态同步”是没有意义的,因为同步是你对对象做的事情,并且没有静态对象这样的事情。 Java中唯一可以是static的东西是变量和方法。


P.S.,要回答你的问题,

当一个线程进入一个synchronized块或方法,它必须获得指定对象上的锁,如果线程不已经有对象锁定。因此,如果f.grumble()在我上面的示例中调用mumble(),那么线程在进入grumble()例程时必须首先获得f的锁定,然后在仍然保持该锁定的同时还必须获得Foobar.class的锁定。