2014-12-04 56 views
0

如下面的示例所示,一旦对call方法中的对象执行了锁定,则不需要其他方法来使用​​关键字。多级java行为同步

public class Prac 
{ 
    public static void main(String[] args) 
    { 
     new Prac().call(); 
    } 

    private synchronized void call() 
    { 
     further(); 
    } 

    private synchronized void further() 
    { 
     oneMore(); 
    } 

    private synchronized void oneMore() 
    { 
     // do something 
    } 
} 

但是,如果我还添加​​关键字furtheronceMore,这样的遭遇做什么java吗? java是否检查是否需要锁定?或者当方法调用位于同一堆栈中时,它只是继续执行,而不检查是否需要锁定,因为锁定已经获取。

注意:我怀疑java是如何在这种情况下行为的,我不确定,但我认为它与偏向锁定不同。

回答

4

事实上,java会在每次进入同步方法时检查当前线程是否有锁。

private synchronized void oneMore() 
    { 
     // do something 
    } 

这相当于

private void oneMore(){ 
     synchronized(this){ 
     // do something 
    } 
} 

但是因为事实上,在Java中的内在锁是可重入的;如果一个线程拥有锁定,那么一旦它进入另一个同步块,就不会重新获取它,如同你的例子。否则,这会造成死锁。

更新:在下面回答您的评论。从Java并发性实践:

Reentrancy is implemented by associating with each lock an acquisition count 
and an owning thread. When the count is zero, the lock is considered unheld. 
When a thread acquires a previously unheld lock, the JVM records the owner 
and sets the acquisition count to one. If that same thread acquires the lock 
again, the count is incremented, and when the owning thread exits the 
synchronized block, the count is decremented. When the count reaches zero, 
the lock is released. 

因此,检查是否锁被收购,相当于一个if语句(或多或少),该变量保存拥有线程等于或不线程试图收购锁。

但是,正如您所指出的那样,private方法中不需要synchronized关键字。一般来说,您应该尝试删除不必要的同步,因为这通常会导致性能下降。

+0

检查锁是否会增加任何性能开销? – Batty 2014-12-04 09:35:46