몇 가지 정적 변수를 지연 초기화하는 인스턴스 메소드를 작성하려고합니다. 내가 초기화하는 개체는 변경할 수 없으며 개체의 참조는 다른 인스턴스 또는 클래스의 정적 메서드에 의해 변경되지 않습니다. 많은 다른 스레드에서 클래스의 여러 인스턴스가있을 수 있지만 초기화 코드를 두 번 이상 실행하지 마십시오. 메서드는 수퍼 클래스의 메서드를 재정의하므로 초기화는 인스턴스 메서드에서 수행해야합니다. 내가 사용하고있는 나의 접근 방식은 다음과 같습니다.다중 스레드 상황에서 정적 변수를 지연 초기화하는 중
private static volatile boolean isPrepared;
private static volatile Object object1;
private static volatile Object object2;
private static volatile Object object3;
@Override
void prepare() {
synchronized (this.getClass()) {
if (isPrepared) { return; }
object1 = expensiveCalculation1();
object2 = expensiveCalculation2();
object3 = expensiveCalculation3();
isPrepared = true;
}
}
나는 초기화가 하나의 동기화 블록에서 발생하기 때문에 인스턴스 이제까지 true
않는 object1
, object2
및 object3
모든 null이 아닌 것으로 isPrepared
을 관찰하는 것은 불가능하다고 가정입니다. 또한 잠금 장치가 this
일 때 prepare()
을 synchronized
으로 단순히 선언하면 작동하지 않는다고 가정합니다. 내 가정이 맞습니까? 또한 함께 초기화 된 것으로 간주 할 때 여러 변수를 volatile
이라고 표시하는 것이 좋습니까? 아니면 단일 Immutable 클래스에 함께 묶어야합니까? 당신이 필요로하는 다음 모든이 volatile
변수없이 동기화이기 때문에 불변의 객체로 모든 게으르게 초기화 상태를 묶기
답변 해 주셔서 감사합니다. 나는 변수들을 하나의 휘발성 변수로 묶는 접근법을 사용할 것이라고 생각한다. 그러나 휘발성과 동기화 된 블록의 결합이 언급 한 복제 가능성을 완전히 없애는 가장 간단한 방법이 아닙니까? –
예, 그렇습니다. 휘발성 변수에 값이 있는지 먼저 확인한 다음 필요한 경우 동기화 된 블록을 입력하십시오. –
좋은 지적. var가 이미 있으면 다른 스레드를 기다리는 것을 원하지 않을 것입니다. 휘발성 변수 값을 두 번 확인해야합니다. 한 번 동기화 된 블록이 필요한지 한 번 확인하고 블록의 시작 부분에 한 번 확인해야합니까? 초기 검사가 동기화되지 않았기 때문에 동기화 된 블록을 입력 할 때까지 다른 스레드에서 초기화가 완료되었을 수 있습니다. –