2013-03-04 2 views
5

왜 아래 코드가 교착 상태가되지 않습니까? 내 말은 getNumber (.)를 호출하면 클래스 Test의 객체가 잠겨져 getNumber2 (.)에 액세스 할 수 없어야합니다.같은 객체의 동기화 된 메서드에서 동기화 된 메서드 호출

class Test() { 
    synchronized int getNumber(int i){ 
     return getNumber2(i); 
    } 

    synchronized int getNumber2(int i) { 
     return i; 
    } 

    public static void main(String[] args) { 
     System.out.println((new Test()).getNumber(100)); 
    } 
} 

출력 :

100 
+0

비슷한 게시물 : http://stackoverflow.com/questions/5798637/is-it-safe-to-call-a-synchronized-method-from-another-synchronized-method – Walls

+0

예 질문에 동일한 , 문맥은 상당히 다르다. 이 질문에 대해서는 죽은 자물쇠에 대해 물어 보았습니다. – Lovera

답변

19

이것은 자물쇠는 동일한 스레드에 의해 여러 차례 취득 할 수 있다는 것을 의미 재진입 때문이다. Java tutorial에서

:

재진입 동기화 스레드가 다른 스레드가 소유 한 잠금을 획득 할 수

기억합니다. 그러나 스레드는 이미 소유하고있는 잠금을 획득 할 수 있습니다. 스레드가 동일한 잠금을 두 번 이상 획득하도록 허용하면 재진입 성 동기화가 가능합니다. 이것은 동기화 된 코드가 직접 또는 간접적으로 동기화 된 코드를 포함하는 메소드를 호출하고 두 세트의 코드가 동일한 잠금을 사용하는 상황을 설명합니다. 재진입 동기화가 없다면, 동기화 된 코드는 스레드가 스스로를 차단하는 것을 피하기 위해 많은 추가주의 사항을 취해야합니다.

JLS의 관련 부분은 §17.1. Synchronization입니다 :

자바 프로그래밍 언어는 스레드 간의 통신을위한 여러 메커니즘을 제공합니다. 가장 기본적인 방법은 모니터를 사용하여 구현되는 동기화입니다. Java의 각 오브젝트는 스레드가 잠 그거나 잠금 해제 할 수있는 모니터와 연관됩니다. 한 번에 하나의 스레드 만 모니터에 잠금을 유지할 수 있습니다. 해당 모니터를 잠 그려는 다른 스레드는 해당 모니터에서 잠금을 얻을 수있을 때까지 차단됩니다. 스레드는 특정 모니터를 여러 번 잠글 수 있습니다. 각각의 잠금 해제는 하나의 잠금 조작의 효과를 역전시킵니다.

그렇지 않은 경우가있을 수있을 때까지
4
스레드가 동기화 방법을 입력 할 때 때문에이 교착 상태로 이어질하지 않습니다

, 그것은 다음, 그것은 this에 대한 잠금을 가지고 있음을 확인하고 있습니다 무엇, 그것은 대기 자물쇠와 그것을 얻으십시오.

스레드가 두 번째 동기화 메소드에 들어가면 이미 this 객체에 잠금이 설정되어있어 차단하지 않고 메소드에 들어갈 수 있습니다.

관련 문제