문제

Java에서 같은 개체에서 두 번 동기화하면 이상한 동작이 발생하는지 궁금합니다.

시나리오는 다음과 같습니다

pulbic class SillyClassName {

    object moo;
    ...
    public void method1(){
        synchronized(moo)
        {
            ....
            method2();
            ....
        }
    }

    public void method2(){
        synchronized(moo)
        {
            doStuff();
        }
    }
}

두 방법 모두 객체를 사용하고 동기화됩니다. 첫 번째 메소드가 호출 할 때 두 번째 메소드가 잠겨 있으므로 중지됩니까?

나는 그것이 같은 스레드이기 때문에 그렇게 생각하지 않지만 다른 이상한 결과가 확실하지 않습니다.

도움이 되었습니까?

해결책

요각

동기화 된 블록 사용 요각 잠금 장치는 스레드가 이미 잠금을 고정하면 문제없이 재산을 재구성 할 수 있음을 의미합니다. 따라서 코드는 예상대로 작동합니다.

바닥을 참조하십시오 자바 튜토리얼 페이지 본질적인 잠금 및 동기화.

2015-01 년 현재 인용…

재진입 동기화

스레드는 다른 스레드가 소유 한 잠금을 얻을 수 없다는 것을 상기하십시오. 그러나 스레드는 이미 소유 한 자물쇠를 얻을 수 있습니다. 스레드가 동일한 잠금을 두 번 이상 얻을 수 있도록하면 재진입 동기화. 이는 동기화 된 코드가 직간접 적으로 동기화 된 코드를 포함하는 메소드를 호출하고 두 코드 세트가 동일한 잠금을 사용하는 상황을 설명합니다. 재진입 동기화가 없으면 동기화 된 코드는 스레드 자체가 차단하지 않도록 많은 추가 예방 조치를 취해야합니다.

다른 팁

나는 우리가 당신이하려는 일에 재진입 잠금 장치를 사용해야한다고 생각합니다. 여기 스 니펫이 있습니다 http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/reentrantlock.html.

재진입 자물쇠가 무엇을 의미합니까? 단순히 잠금과 관련된 획득 카운트가 있고, 잠금 장치를 보유하는 스레드가 다시 획득되면, 획득 카운트가 증가하고 잠금 장치가 두 번 릴리스 되려면 잠금을 방출해야합니다. 이것은 동기화 된 의미와 유사합니다. 스레드가 스레드가 이미 소유 한 모니터로 보호 된 동기화 된 블록으로 들어가면 스레드가 진행될 수 있으며 스레드가 두 번째 (또는 후속) 동기화 된 블록을 종료하면 잠금이 해제되지 않지만 해제됩니다. 첫 번째 동기화 된 블록을 종료하면 해당 모니터로 보호 된 입력했습니다.

나는 그것을 시도하지 않았지만, 당신이 위에서 가지고있는 일을하고 싶다면, 당신은 재진입 잠금 장치를 사용해야한다고 생각합니다.

Java는 동일한 스레드로 하나의 객체의 중첩 잠금 장치를 완전히 지원하는 것으로 보입니다. 즉, 스레드에 외부와 내부 잠금 장치가있는 경우 다른 스레드가 동일한 객체를 잠그려고하면 두 번째 스레드가 매달릴 때까지 둘 다 첫 번째 스레드에서 자물쇠가 해제되었습니다.

내 테스트는 Java 6 SE에서 수행되었습니다.

아무 문제 없습니다. 예에서 (코드를 수정하여 얻을 수있는 컴파일 경고를 제거하면;)) 동기화는 Method1 및 Method2의 블록이 동시에 실행되지 않도록합니다.

그것은 일종의 동기화 지점입니다. :)


편집 : 죄송합니다. 질문의 일부를 놓쳤지만 Phill은 대답했습니다. 요약하자면, 단일 스레드는 자체적으로 교착 상태가 될 수 없습니다.

Java에서 synchronized 메소드의 키워드는 기본적으로 현재 객체와 동기화되므로 사실상 위에서 제안한 것을 암시 적으로 수행합니다.

한 메서드에서 한 객체의 동기화에 문제가 발생하지 않고 다른 메소드에서 동일한 객체에서 동기화하는 데 문제가 발생하지 않습니다.

아니요, 두 번째 방법은 먼저 호출되면 중지되지 않습니다. 홀수 결과가 발생하지 않습니다 (잠금 점검을위한 약간의 오버 헤드 제외. 이것은 크게 중요하지 않습니다. Java 6 이후에는 JVM에서 자물쇠가 거칠어집니다. http://java.sun.com/performance/reference/whitepapers/6_performance.html )

예를 들어 java.util.vector의 소스 코드를 살펴보십시오. 동기화 된 메소드 내에서 다른 동기화 된 메소드에 대한 통화가 많이 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top