2015-01-12 6 views
3

자바 동시성은 '실제로 자바 동시성'에서 잠금 재진입에 대한 몇 가지 예제 코드입니다 :재진입 잠금 연습 여기

class Widget { 
public synchronized void doSomething() { 
    System.out.println(toString() + ": calling superclass doSomething"); 
} 


} 

class LoggingWidget extends Widget { 
public synchronized void doSomething() { 
    System.out.println(toString() + ": calling subclass doSomething"); 
    super.doSomething(); 
} 
} 

이 책은 설명하고 그 위의 코드에서 ... "를 해봐요 방법 때문에 Widget과 LoggingWidget은 둘 다 동기화되며, 진행하기 전에 위젯에 대한 잠금을 획득하려고 시도합니다. "

위의 코드를 실행하여 고유 잠금을 관찰했습니다. 위의 인용문은 스레드가 위젯 개체의 본질적인 잠금을 획득한다는 것을 암시하는 것으로 보이지만 스레드에서 LoggingWidget에 대한 잠금을 획득한다는 것이 관찰되었습니다. 획득 수를 확인하는 방법을 모르겠으므로이를 관찰 할 수 없었습니다.

LoggingWidget/Widget의 이름이 같은 의미로 사용 되었습니까? 아니면 위젯 객체에 대한 잠금을 구체적으로 준수해야합니까?

편집 : 전체 발췌

재입는 잠금 행동의 캡슐화를 용이하게하고, 따라서 객체 지향 동시 코드의 개발을 단순화합니다. 재진입 잠금이 없으면 서브 클래스가 synchronized 메소드를 대체 한 후 수퍼 클래스 메소드를 호출하는 Listing 2.7의 매우 자연스러운 코드 은 교착 상태가됩니다. 위젯과 LoggingWidget의 doSomething 메소드가 모두 동기화되었으므로 계속 진행하기 전에 각 위젯에 대한 잠금을 에 획득하려고 시도합니다. 그러나 내재 된 자물쇠가 인 경우 재 호출이 허용되지 않는 경우 이미 보유 된 것으로 간주되어서 자물쇠를 획득 할 수 없으므로 스레드는 영구적으로 대기를 중지하여 을 획득 할 수 없으므로 super.doSomething을 호출 할 수 없습니다. Reentrancy는 이와 같은 상황에서 교착 상태를 방지합니다.

+0

하나의 스레드 교착 상태 - 나에게 이상하게 보임 – gstackoverflow

답변

3

예 OOP 상속 원칙에 따라 LoggingWidget/Widget은 상호 교환 방식으로 사용됩니다. LoggingWidget 객체는 Widget 클래스 객체이기도합니다. 이 예제에서는 하나의 객체 인스턴스 만 만들어지고 다시 입력 할 동기화 모니터로 사용됩니다.

6

특정 답변을 제공하려면 발췌 부분을 참조하십시오. 이러한 클래스를 다른 방법으로 인스턴스화 할 수 있습니다. 자물쇠가 객체에 고정되어 있으므로 참조가 중요하지 않습니다. 그것을 설명하기 위해 ...

이 클래스 구조는 당신을 밀접하게 흉내냅니다.

public class GenericTest { 
    public static void main(String... args) { 
     Sub sub = new Sub(); 
     sub.go(); 
    } 

    public synchronized void go() { 
     System.out.println("Parent"); 
    } 
} 

class Sub extends GenericTest { 
    @Override 
    public synchronized void go() { 
     System.out.println("Child"); 
     super.go(); 
    } 
} 

실행이 프로그램이 당신을 기쁘게하는 방법으로 잠금을 획득 한 후 더 라인을 실행 중지 (System.in.read 말을()). Java 프로그램의 PID를 찾아서 Jconsole에서 엽니 다. threads 섹션으로 이동하여 잠금을 얻을 때마다 강조 표시하십시오. 다음과 같은 흔적을 볼 수 있습니다. 이 방법은 멤버 변수이므로

my.package.common.GenericTest.go(GenericTest.java:30) 
    - locked [email protected] 
my.package.common.Sub.go(GenericTest.java:42) 
    - locked [email protected] 

로크 현재 개체 문제의 방법을 실행 (this)에있다. 두 자물쇠가 모두 [email protected]에 있는지 확인하십시오.

[편집]

은 특정한 경우에 맞게 내 대답을 편집.

+0

명확성을 위해 전체 발췌 부분이 추가되었지만 답과 @ Semyon의 대답으로이 지점이 명확 해졌습니다. 불행히도 대답은 하나만 선택할 수 있습니다. – sotn