본문 바로가기
츄Log/기타 끄적

싱글톤 안전하게 초기화하기 (thread-safe initialization)

by 츄츄🦭 2023. 12. 3.
728x90

안녕하세요!

지난번 Double Check Locking을 싱글톤 패턴을 통해 알아보면서, 싱글톤 객체 초기화를 개발자가 처리하는 것이 아닌 JVM에게 위임하여 해결할 수는 없을까? 고민하였습니다. 

 

JVM에게 위임하여 thread-safe하게 초기화하는 4가지 방법을 소개하겠습니다.

 

1. static field를 사용한 Early Initalization (Eager Initialization) 

public class EarlyInitSingleton {
    private static final EarlyInitSingleton INSTANCE = new EarlyInitSingleton();
    public static EarlyInitSingleton getInstance() {
        return INSTANCE;
    }
}

클래스가 로드될 때 생성되는 제일 간단한 방법입니다.

싱글톤 클래스가 많은 리소스를 사용하지 않는 경우에는 유용하지만 초기화에 많은 리소스가 필요하거나 사용 빈도가 낮다면 적절하지 않은 방법일 수 있습니다.

 

2. static block을 사용한 Early(Eager) Initalization

public class EarlyInitSingleton {
    private static final EarlyInitSingleton INSTANCE;
    static {
    	INSTANCE = new EarlyInitSingleton();
    }
    
    public static EarlyInitSingleton getInstance() {
        return INSTANCE;
    }
}

이것도 1번 방법처럼 클래스가 로드될 때 생성되지만 다른 점은 static 블럭을 활용하여 인스턴스 예외처리 등 추가적인 설정을 할 수 있습니다.

 

3. enum을 사용한 Early(Eager) Initalization

public enum EnumSingleton {
    INSTANCE;

    // other methods...
}

effective java에 나오는 내용이죠. 

enum 클래스는 한 번만 초기화 되는 점을 이용하여 만들어낸 방법입니다. 

 

4. inner static class를 사용한 On demand(Lazy) Initialization (Bill Pugh singleton pattern

public class InitOnDemandSingleton {
    private static class InstanceHolder {
        private static final InitOnDemandSingleton INSTANCE = new InitOnDemandSingleton();
    }
    public static InitOnDemandSingleton getInstance() {
        return InstanceHolder.INSTANCE;
    }
}

싱글톤 클래스에 private inner static class를 포함하여 싱글톤 객체를 생성합니다.

싱글톤 클래스가 로드될 때 InstanceHolder는 메모리에 로드되지 않고 getInstance()를 호출할 때 로드되어 싱글톤 클래스 인스턴스를 생성합니다.

지연 초기화를 사용할 수 있고 스레드 안정성도 보장하기에 가장 많이 사용되는 패턴이 아닐까 합니다. 


감사합니다! 

궁금한 점은 댓글 남겨주세요 :) 

 

참고 : https://www.baeldung.com/java-singleton-double-checked-locking

728x90