2012-08-16 2 views
3

다음 예제를 감안할 때 : enter image description here클래스를 확장 할 때 재진입 잠금?

이 예는 "연습 자바 동시성"에서이다.

코멘트가 :

위젯과 LoggingWidget의 해봐요 방법은 모두 동기화되기 때문에, 각각 진행하기 전에 위젯에 대한 잠금을 획득하려고합니다.

LoggingWidget 클래스의 doSomething 메소드가 Widget에서 잠금을 가져와야하는 이유는 무엇입니까? 그렇다면 doSomethingLoggingWidget에있는 synchronized은 쓸모가 없습니다. 맞습니까?

답변

2

LoggingWidget 클래스의 doSomething이 위젯의 ​​잠금을 획득해야하는 이유는 무엇입니까?

당신이 두 스레드가 동시에 LoggingWidget#doSomething()를 실행할 수 있는지 확인하려면 가정하면 (이 예에서는 개체가 인쇄 문 및 super.doSomething()에 대한 호출 사이에 수정되지 않았는지 확인 할 수 있습니다) 다음 메서드를 동기화해야합니다.

스레드 (T1)이 LoggingWidget#doSomething()으로 시작하여 해당 개체를 인쇄하면 다른 스레드 (T2)가 LoggingWidget#doSomething()도 실행을 시작할 수 있고 (메서드가 동기화되지 않음) 개체를 다시 인쇄 한 다음 T2를 인쇄 할 수 있습니다. super.doSomething()을 실행하면 개체가 변경되고 T1은 super.doSomething()을 실행하지만 개체의 상태는 T2가 변경된 동안 인쇄 된 것과 다를 수 있습니다.

방지하는 한 가지 방법은 메서드를 동기화하는 것입니다.

위젯과 LoggingWidget의 doSomething 메소드가 모두 동기화되었으므로 각각의 키는 동기화되기 전에 계속 진행하기 전에 위젯에서 잠금을 획득하려고 시도합니다.

재진입은 주어진 스레드가 이미 보유하고있는 잠금을 다시 획득 할 수 있음을 의미합니다. 이 경우 스레드가 LoggingWidget#doSomething()을 입력하면 메서드가 동기화되므로 this을 얻습니다. super.doSomething()이 실행되면 동일한 잠금을 다시 획득해야합니다. 본질적인 잠금은 재진입 성이 아니 었으며, 스레드는 이미 블록킹되어 영원히 잠겨 있었고 이미 보유하고있는 잠금을 얻으려고 시도했지만 교착 상태를 해제하지는 않습니다.

+0

"이 경우 스레드가 LoggingWidget # doSomething()에 들어갈 때 메서드가 동기화 되었기 때문에이 메서드를 가져오고 super.doSomething()을 실행하면 동일한 잠금을 다시 획득해야합니다." 하지만 왜 같은 잠금 장치입니까? '이'는 '슈퍼'가 아니지? 아마도 여기에 기본적인 것들이 빠져있을 것입니다. –

+0

@ 존도 그렇다면이 슈퍼 **는 ** 같은 대상입니다!'Widget w = new LoggingWidget();'이라고 쓰면'LoggingWidget'과'Widget' 둘 다인'w'라는 객체가 하나뿐입니다. 따라서'synchronized (this)'는 두 클래스 모두에서'w'를 잠급니다. 그 말이 맞는다면. – assylias

+0

맞아, 정말 간단하다, 미안, 아마 잠을 좀 자야 해. :) –

0

재진입 잠금은 이미 잠긴 개체에 대한 잠금을 다시 획득하여 중복을 방지합니다. 자, 잠금 해제가 모든 잠금을 해제하지는 않습니다. JVM은 내부적으로 개체에서 잠금을 얻을 때마다 증가하고 잠금이 해제 될 때마다 감소 할 카운터를 유지합니다. 따라서이 메커니즘은 데드 록을 피할뿐만 아니라 카운트를 유지하여 정확성을 유지합니다.

관련 문제