문제

그것은에서 언급된 자바 메모리는 모델:스레드를 종료하면 동기화된 블록의 일부로 방출된 모니터,JMM 요구하는 지역 프로세서 캐시 플러시합니다.마찬가지로, 의 일환으로 획득하 모니터링을 입력할 때 동기화된 블록,지역 캐시 무효화되도록 후속 읽는 것이 바로 이동 메인 메모리 및 로컬 캐시입니다.

왜에는 코드는 나를 선언해야 합니다 인스턴스로부터 휘발성할 때는 두 번째 스레드가 동기화를 블로 직접 이동합니다 주요 메모리??

public final class MySingleton {
  private static MySingleton instance = null;
  private MySingleton() { } 
  public static MySingleton getInstance() {
    if (instance == null) {
      synchronized (MySingleton.class) {
        if (instance == null) {
          instance = new MySingleton();
        }
      }
    }
    return instance;
  }
}

내가 말할 때는 또 다른 스레드 동기화 차단 및 두 번째 확인하여야에서 업데이트 주요 메모리로서 언급된다.

도움이 되었습니까?

해결책

경쟁 조건은 이것입니다:

  1. 스레드 보고 instance == NULL 고 이 코드를 실행 instance = new MySingleton();.쓰기 instance 은 보이지만 쓰 MySingleton 는 아직 없습니다.

  2. 실 B 보고 instance != NULL 며 작동 시작에 인스턴스입니다.

  3. 실 B 입니다 지금 작업하는 개체의 건축 그것은 볼 수 없습니다.

instance 휘발성 문제를 해결합으로 JDK 메모리 사양으로의 JDK5,보증 쓰는 비휘발성 물체를 볼 수 없 순서와 관련하여 쓰 휘발성 개체입니다.그래서 어떤 쓰레드는 보 instance != NULL 를 참조해야합니다 인스턴스 자체입니다.

다른 팁

volatile을 선언해야합니다. 그렇지 않으면 getInstance ()에 대한 두 호출이 동일한 인스턴스를 반환 할 것이라는 보장이 없습니다.

주 메모리가 액세스 할 보장은 없으며 캐시 일관성 값 만 있습니다.I.E.E. 모든 스레드가 동일한 값을 볼 수 있습니다.

btw : 당신은 물론 필요한 것보다 훨씬 더 복잡합니다.필요한 것은

입니다
public enum MySingleton {
     INSTANCE;
}
.

는 똑같은 것입니다.

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