본문 바로가기
com.theory

단일체(singleton) 패턴

by Younji! 2020. 5. 26.

디자인 패턴하면 가장 먼저 생각나는 싱글톤 패턴인데, 이는 단 하나의 클래스 인스턴스만을 갖도록 보장하고 전역적인 접근을 갖는다.

보통 싱글톤 패턴은 안티패턴으로 OCP에 위배되는 경우가 발생해서 테스트, 디버깅이 어려워지고 멀티 스레드 환경에서 동기화 처리를 안하면 여러 개가 생성된다고 얘기하며(어지간하면 피하라고..) 유의해서 사용하면 공통으로 객체를 사용되는 데 구현할 수 있다.

Logger나 Thread / DB Connection Pool도 싱글톤 으로 구현돼있다.

 

보통 싱글톤 패턴에 동기화라면 서브클래싱해서 아래와 같이 작성한다.

public class Singleton {
    private static Singleton singleton;

    public syncronized Singleton getInstance() {
        if (signleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

synchorized는 여러 한계가 있는데 퍼포먼스가 떨어지고, 다른 스레드를 대기시켜 데드락을 유발시킬 수도 있다. 보통 최소한의 syncronized만 사용하라고 기술되어있다. 이를 개선해서 아래와 같이 구현할 수 있다.

initialization-on-demand holder

public class Something {
    private Something() {}

    private static class LazyHolder {
        static final Something INSTANCE = new Something();
    }

    public static Something getInstance() {
        return LazyHolder.INSTANCE;
    }
}

 

JLS에 명시된 class 초기화 의해 클래스 초기화를 지연시킬 수 있고 해당 처리 과정에 따라 getInstance() 참조가 일어나서야 LazyHolder 클래스가 초기화되고 그제서야 INSTANCE를 참조하기 때문에 추가로 동기화에 대한 오버헤드가 발생하지 않는다.

추가적으로 Lazy가 아닌 Enum 등을 사용한 Eager Initialization 방법도 있다.

 

 

마지막으로.. 갑자기 급 궁금해서 -> 스프링에 싱글톤 빈 스코프와 싱글톤 패턴은 뭐가 다를까?

정의하자면 싱글톤 패턴에 클래스 로더 당 단 하나의 인스턴스를 갖는 것이고 싱글톤 빈은 스프링 컨테이너 당 하나의 인스턴스를 갖는 것이다. 두 가지 개념이 동일한 것은 아니다.

댓글