이것은 더 복잡한 시스템으로 작업 할 때 자주 겪는 문제이며 해결 방법을 찾지 못했습니다. 일반적으로 공유 객체의 주제에 대한 변형을 포함하며, 그 구성과 초기화는 반드시 두 단계로 구분됩니다. 이것은 일반적으로 애플릿과 유사한 아키텍처 요구 사항 때문에 발생하므로 구성 및 초기화를 통합하라는 대답은 유용하지 않습니다. 시스템은 늦어도 Java 4를 대상으로해야하기 때문에 나중에 JVM에서만 지원되는 지원은 유용하지 않습니다. 이 시작할 때까지 설정 할 수 없기 때문에Java에서 thread-safe 한 번만 읽기 - 값을 만드는 방법은 무엇입니까?
public class MyClass
{
private /*ideally-final*/ SomeObject someObject;
MyClass() {
someObject=null;
}
public void startup() {
someObject=new SomeObject(...arguments from environment which are not available until startup is called...);
}
public void shutdown() {
someObject=null; // this is not necessary, I am just expressing the intended scope of someObject explicitly
}
}
내가 여기서 someObject 결승전을 할 수 없습니다 :
예로서,의 난과 같이 응용 프로그램 프레임 워크에 맞게 구성되어 클래스가 있다고 가정 해 보자()가 호출됩니다. 그러나 나는 그것의 write-once 의미를 반영하고 다중 스레드에서 직접 액세스 할 수 있어야하며, 바람직하게는 동기화를 피하는 것이 좋습니다.
표현하고 finalness의 정도를 적용 할 수있는 아이디어, 내가 같은, 일반적인 컨테이너를 만들 수 있다고 추측 (UPDATE -이 클래스의 수정 스레딩 sematics) :
public class WormRef<T>
{
private volatile T reference; // wrapped reference
public WormRef() {
reference=null;
}
public WormRef<T> init(T val) {
if(reference!=null) { throw new IllegalStateException("The WormRef container is already initialized"); }
reference=val;
return this;
}
public T get() {
if(reference==null) { throw new IllegalStateException("The WormRef container is not initialized"); }
return reference;
}
}
다음 MyClass
에서, 위, 수행
-
: 나를 위해 몇 가지 질문을 제기
- 더 나은 방법이나 기존 Java 객체 (Java 4에서 사용할 수 있어야합니까?)가 있습니까?
private final WormRef<SomeObject> someObject;
MyClass() {
someObject=new WormRef<SomeObject>();
}
public void startup() {
someObject.init(new SomeObject(...));
}
public void sometimeLater() {
someObject.get().doSomething();
}
둘째로, 스레드 안전의 관점에서 :
- 이 스레드 안전 제공하는 다른 스레드가
set()
가 호출 된 때까지someObject.get()
에 액세스하지 않습니다. 다른 스레드는 startup()과 shutdown() 사이의 MyClass에서만 메서드를 호출합니다. 프레임 워크가이를 보장합니다. - 완전히 동기화되지 않은
WormReference
컨테이너가 주어지면 어느 JMM에서도 null이 아니며 SomeObject에 대한 참조도 아닌object
값을 볼 수 있습니까? 즉, JMM은 객체가 할당되었을 때 힙에 발생한 모든 값이 스레드가 객체의 메모리를 관측 할 수 없음을 항상 보장합니다. 할당은 명시 적으로 할당 된 메모리를 0으로 만들기 때문에 대답은 "예"라고 생각하지만 주어진 메모리 위치에서 관찰되는 CPU 캐싱 결과가 있습니까? - 적절한 다중 스레드 의미론을 보장하기 위해 WormRef.reference를 volatile 화하는 것으로 충분합니까?
주이 질문의 주요 추력 표현하고 수있는없이 finalness에게 someObject
의을 적용 하는 방법은 실제로 그것을 final
표시; 보조는 thread-safety에 필요한 것입니다. 즉, 이것의 스레드 안전 측면에 너무 매달 리지 마십시오.다음과 같이
은 허용 될 수 없습니다? – MSN
@MSN : 사실 대부분의 경우 다른 스레드는 초기화가 완료 될 때까지 시작되지 않습니다. –
OP 모두가 내 질문에 대한 답을 모욕 한 것이므로 대답을 삭제했습니다. 이것은 말이되지 않습니다. – BalusC