첫째 : 동기화 된 키워드를 사용하는 경우
다시 코드 재주문는 결코 JMM 사양에 따라 반응이 없습니다.
위의 진술은 완전히 정확하지 않습니다. JMM은 happen-before 관계를 정의했습니다. JLS는 프로그램 순서와 발생 이전 순서 만 정의합니다. 17.4.5. Happens-before Order을 참조하십시오.
명령의 순서 변경에 영향을 미칩니다. 예를 들어,
int x = 1;
synch(obj) {
y = 2;
}
int z = 3;
이제 위의 코드 조각에 대해 다음 유형의 순서 재 지정이 가능합니다.
synch(obj) {
int x = 1;
y = 2;
int z = 3;
}
위의 내용은 유효한 순서입니다.
Roach Motels and The Java Memory Model을 참조하십시오.
synch(obj) {
int z = 3;
y = 2;
int x = 1;
}
위의 내용은 또한 유효한 순서 재 지정입니다.
y = 2는 잠금을 획득하고 잠금을 해제하기 전에 만 실행될 수 있습니다. 이는 JMM이 보증 한 것입니다. 또한 다른 스레드에서 올바른 효과를 보려면 동기화 된 블록 내에서만 y에 액세스해야합니다.
이제 DCL에 왔습니다.
DCL 코드를 참조하십시오.
if (singleton == null)
synch(obj) {
if(singleton == null) {
singleton == new Singleton()
}
}
return singleton;
지금 위의 접근 방식의 문제는 :
singleton = new Singleton()
는 단일 명령어가 아닙니다. 그러나 일련의 지시들. 생성자를 완전히 초기화하기 전에 먼저 Singleton 참조에 객체 참조가 할당 될 가능성이 큽니다.
따라서 이 발생하면 다른 스레드가 null이 아닌 것으로 간주하여 부분적으로 구성된 객체를 보는 것이 가능합니다.
위의 효과는 단일성을 휘발성으로 만들어 제어 할 수 있으며 이는 또한 보증 및 가시성 이전에 발생합니다.
코드 양식에서 생각하고있는 특정 이중 확인 잠금 관용구를 게시하면 도움이됩니다. DCL에는 몇 가지 변형이 있습니다. –
가능한 복제본 [Java에서 이중 검사 잠금이 끊긴 이유는 무엇입니까?] (0120-555-3300) –