2014-12-04 6 views
0

아래 예제와 같이 call 메서드의 객체에 잠금을 설정하면 synchronized 키워드를 추가로 가질 필요가 없습니다.여러 수준의 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 
    } 
} 

하지만, 난 여전히 같은 만남에 무엇을 자바 furtheronceMoresynchronized 키워드를 추가하면? Java가 잠금이 필요한지 여부를 확인합니까? 또는 메소드 호출이 같은 스택에 있기 때문에 잠금이 이미 필요한지 여부를 확인하지 않고 잠금이 이미 획득되었으므로 진행됩니다.

참고 : 의심의 여지가 이런 상황에서 자바가 어떻게 동작 할 것인지는 확실치 않지만, 바이어스 된 잠금과는 다릅니다.

답변

4

사실, java는 동기화 된 메소드에 들어갈 때마다 현재 스레드가 잠금을 가지고 있는지 확인합니다.

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

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

에 그러나 때문에 자바의 고유 잠금 재진입 사실의 동일합니다; 쓰레드가 잠금을 가지고 있다면, 당신이 예제에서와 같이 다른 동기화 된 블록을 입력하면 다시 획득하지 않습니다. 그렇지 않으면 교착 상태가 발생합니다.

업데이트 : 아래에서 귀하의 의견에 답변하십시오. 실제로 자바 Concurency에서 :

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. 

따라서 잠금이 획득 한 경우 검사에 해당 소유 스레드를 유지하는 변수가 취득하려고 스레드 같거나 아님을 문 경우 (자세한 이하)를 자물쇠.

그러나 지적했듯이 비공개 메소드에는 synchronized 키워드가 필요하지 않습니다. 일반적으로 성능 저하로 이어지는 불필요한 동기화를 제거해야합니다.

+0

잠금을 확인하면 성능 오버 헤드가 추가됩니까? – Batty