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()
이 실행되면 동일한 잠금을 다시 획득해야합니다. 본질적인 잠금은 재진입 성이 아니 었으며, 스레드는 이미 블록킹되어 영원히 잠겨 있었고 이미 보유하고있는 잠금을 얻으려고 시도했지만 교착 상태를 해제하지는 않습니다.
"이 경우 스레드가 LoggingWidget # doSomething()에 들어갈 때 메서드가 동기화 되었기 때문에이 메서드를 가져오고 super.doSomething()을 실행하면 동일한 잠금을 다시 획득해야합니다." 하지만 왜 같은 잠금 장치입니까? '이'는 '슈퍼'가 아니지? 아마도 여기에 기본적인 것들이 빠져있을 것입니다. –
@ 존도 그렇다면이 슈퍼 **는 ** 같은 대상입니다!'Widget w = new LoggingWidget();'이라고 쓰면'LoggingWidget'과'Widget' 둘 다인'w'라는 객체가 하나뿐입니다. 따라서'synchronized (this)'는 두 클래스 모두에서'w'를 잠급니다. 그 말이 맞는다면. – assylias
맞아, 정말 간단하다, 미안, 아마 잠을 좀 자야 해. :) –