2013-05-14 3 views
2

싱글 톤 클래스 {지연 초기화}가 나타났습니다. 코드는지연 초기화 희박 변수가있는 싱글 톤 클래스

// Singleton reference for this class 
    private static volatile FileProperties INSTANCE = null; 

    public static FileProperties getInstance() { 
      if (INSTANCE == null) { 
       synchronized (FileProperties.class) { 
        if (INSTANCE == null) { 
         INSTANCE = new FileProperties(); 
        } 
       } 
      } 
      return INSTANCE; 
     } 

내 질문에 우리가 동기화에 의해 우리가 이미 스레드 안전을 돌보는 때문에 휘발성 로 인스턴스를 만들어지고 이익이 무엇이며 다음과 같이합니다. 이 시나리오에서 휘발성의 이점이 있습니까?

+1

http://jeremymanson.blogspot.co.uk/2008/05/double-checked-locking.html –

+1

이 이중 검사 잠금은 INSTANCE 변수에 널이 아닌 값이 할당 될 수 있다는 점에서 잠재적 인 오류가 있습니다 , * 전에 * FileProperties의 생성자가 완전히 실행되었습니다. 물론 생성자가 비어 있으면 상관 없습니다. –

+1

@JakobJenkov는 분명히 알만한 가치가 있습니다. ** IF ** 인스턴스는 휘발성이 아닙니다. – assylias

답변

5

volatile이없는 이중 검사 잠금은 Java에서 스레드로부터 안전하지 않기 때문입니다. 코드의

public class SomeClass { 
    private static class SomeClassHolder { 
     public static final SomeClass INSTANCE = new SomeClass(); 
    } 

    public static SomeClass getInstance() { 
     return SomeClassHolder.INSTANCE; 
    } 

    private SomeClass() {} 

} 

그 부분을 JVM의 행동이 SomeClassHolder을로드에 SomeClass의 인스턴스를 생성하기 때문에, :

스레드 안전 게으른 초기화 싱글 톤을 만드는 가장 간단한 방법은 다음과 같이 클래스 홀더를 만드는 것입니다 getInstance()의 처음 사용 (SomeClass가 클래스 로더에 의해로드 될 때가 아님).

전혀 동기화 할 필요가 없습니다. 왜냐하면 JVM이 당신을 위해 그것을하고 있기 때문입니다.

+0

이중 검사 잠금은 '휘발성'(Java 1.5)의 "발생 전"현상이 도입 된 이후 스레드 안전입니다. 또한 개인 생성자가 누락되었습니다. – Bohemian

+1

DCL *은 Java 1.5 이상에서 Java에서 스레드로부터 안전합니다. * volatile *을 사용하는 한. (나는 그것을 사용하지 않을 것이지만 스레드로부터 안전합니다.) –

+0

@Bohemian :'volatile'은 Java 1.0에서였습니다. 메모리 모델이 1.5로 변경되었으므로 올바르게 구현 된 DCL은 스레드로부터 안전합니다. –