읽기 about DCL in Wikipedia, DCL 및 제안 된 솔루션의 문제에 대해 궁금한 점이 있었는데, 즉 volatile
키워드가 필요한 이유는 무엇입니까? 문제는 간단히 말해서, DCL을 사용하면 부분적으로 생성 된 객체가 스레드에 의해 사용되는 경우가있을 수 있습니다. (JAVA 5+에 대한) 제안 된 솔루션 :JAVA에서 이중 확인 잠금
// Works with acquire/release semantics for volatile
// Broken under Java 1.4 and earlier semantics for volatile
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) {
synchronized(this) {
result = helper;
if (result == null) {
helper = result = new Helper();
}
}
}
return result;
}
// other functions and members...
}
, 내 질문은 왜 도우미에서 volatile
드롭되지 않는 이유는 무엇입니까? helper = result = new Helper();
에 :
result = new Helper();
helper = result;
이의 시나리오 helper
에서 개체가 완료 될 때까지 참조를 얻을하지 않습니다 당신은 그냥이 줄을 어기면 내가 틀렸다면 정정 해줘,하지만. 그렇지 않니? volatile
의 실적은 어떻습니까?
편집 : 초기화 후 다음 줄이없는 보증을 완전히 초기화 된 개체를 않는 경우, 나는 그것을 메소드를 호출 할 수 없습니다
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) {
synchronized(this) {
result = helper;
if (result == null) {
result = new Helper();
result.someMethod();
helper = result;
}
}
}
return result;
}
}
:이 코드를 가정합니다. 그럴 수있어?
왜냐하면'result = new Helper(); helper = result;'는 helper = result = new Helper();와 정확히 동일합니다. 당신은 무엇이 다른 것이라고 생각 했습니까? – immibis
분명히 모든 동작이 프로그램 순서와 일치하는 전체 순서로 실행된다고 가정합니다. 일반적으로 멀티 스레드 프로그램에서는 그렇지 않습니다. – nosid
@nosid, 나는 초기화 라인이 초기화가 완료되기 전에 주소를받을지도 모른다는 것을 알고 있지만, 초기화가 완료된 후에 만 다음 라인이 실행될 것이라고 가정했다. 그렇지 않으면 객체를 인스턴스화 한 후에 어떻게 객체를 사용할 수 있습니까? 완전히 초기화 된 적이 있다면 지금은 할 수 없습니까? EDIT를 참조하십시오. –