안전하지 않은 초기화

멀티스레드 상황에서 다음의 코드는 싱글톤이 보장되지 않음

public class UnsafeLazyInitialization {
    private static Resource resource;
 
    public static Resource getInstance() {
        if (resource == null)
            resource = new Resource();   // 안전하지 않은 공개
        return resource;
    }
 
    static class Resource { }
}

안전한 초기화 1 - 동기화 메서드

성능이슈가 있으나..

public class SafeLazyInitialization {
    private static Resource resource;
 
    public syncronized static Resource getInstance() {          // syncronized
        if (resource == null)
            resource = new Resource();
        return resource;
    }
 
    static class Resource { }
}

안전한 초기화 2 - 성질 급한 초기화

클래스 로더에 의해 읽혀질때 미리 초기화

public class EagerInitialization {
    private static Resource resource = new Resource;
 
    public static Resource getInstance() { return resource; }
 
    static class Resource { }
}

안전한 초기화 3 - 늦은 초기화 홀더 클래스

JVM은 실제 사용되지 전까지 해당 클래스를 초기화 하지 않는다는 점을 사용

public class ResourceFactory {
    private static class ResourceHolder {
        public static Resource resource = new Resource();
    }
 
    public static Resource getInstance() { return ResourceHolder.resource }
}