업데이트 메모리 동기화가?
-
13-12-2019 - |
문제
그것은에서 언급된 자바 메모리는 모델:스레드를 종료하면 동기화된 블록의 일부로 방출된 모니터,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;
}
}
내가 말할 때는 또 다른 스레드 동기화 차단 및 두 번째 확인하여야에서 업데이트 주요 메모리로서 언급된다.
해결책
경쟁 조건은 이것입니다:
스레드 보고
instance == NULL
고 이 코드를 실행instance = new MySingleton();
.쓰기instance
은 보이지만 쓰MySingleton
는 아직 없습니다.실 B 보고
instance != NULL
며 작동 시작에 인스턴스입니다.실 B 입니다 지금 작업하는 개체의 건축 그것은 볼 수 없습니다.
기 instance
휘발성 문제를 해결합으로 JDK 메모리 사양으로의 JDK5,보증 쓰는 비휘발성 물체를 볼 수 없 순서와 관련하여 쓰 휘발성 개체입니다.그래서 어떤 쓰레드는 보 instance != NULL
를 참조해야합니다 인스턴스 자체입니다.
다른 팁
volatile을 선언해야합니다. 그렇지 않으면 getInstance ()에 대한 두 호출이 동일한 인스턴스를 반환 할 것이라는 보장이 없습니다.
주 메모리가 액세스 할 보장은 없으며 캐시 일관성 값 만 있습니다.I.E.E. 모든 스레드가 동일한 값을 볼 수 있습니다.
btw : 당신은 물론 필요한 것보다 훨씬 더 복잡합니다.필요한 것은
입니다public enum MySingleton {
INSTANCE;
}
.
는 똑같은 것입니다.