디자인 패턴 - 싱글톤 패턴

싱글톤 패턴

  • 정의
    • 싱글톤 패턴은 해당 클래스의 인스턴스가 하나만 만들어지고, 어디서든지 그 인스턴스에 접근할 수 있도록 하기 위한 패턴
  • 사용하는 이유 및 특징
    • 객체 중에 하나만 있으면 될 때 사용하며 스레드 풀, 캐시, 사용자 설정, 레지스트리 설정, 프린터 등이 있다.
    • 자원을 많이 차지하는 객체를 필요할 때만 객체를 만들어 사용할 수 있다.
  • 방법

레거시 코드

/**
 * 멀티스레딩이 해결되지 않은 싱글톤 생성 방식
 */
public class Singleton_step1_with_problem {

    /**
     * 유일한 인스턴스를 저장하기 위한 정적 변수
     */
    private static Singleton_step1_with_problem uniqueInstance;

    /**
     * 생성자를 private으로 선언했기 때문에 해당 클래서에서만 인스턴스를 만들 수 있다
     */
    private Singleton_step1_with_problem() {}

    public static Singleton_step1_with_problem getInstance() {
        if (uniqueInstance == null) uniqueInstance = new Singleton_step1_with_problem();
        return uniqueInstance;
    }

}
  • 동기화를 진행하지 않았을 때 문제점

    • 인스턴스가 두 개 생성될 수 있는 문제

개선 과정 및 코드

  • Synchronized 사용
    • Synchronized를 사용하면 100배정도 성능이 저하된다점 유의
    • 처음에 인스턴스가 생성되고 나면 동기화는 더이상 필요없는데 계속 사용되는 문제 발생
public class Singleton_step2_synchronized {

    /**
     * 유일한 인스턴스를 저장하기 위한 정적 변수
     */
    private static Singleton_step2_synchronized uniqueInstance;

    /**
     * 생성자를 private으로 선언했기 때문에 해당 클래서에서만 인스턴스를 만들 수 있다
     */
    private Singleton_step2_synchronized() {}

    /**
     * synchronized 동기화 처리 -> 멀티스레드 해결
     */
    public static synchronized Singleton_step2_synchronized getInstance() {
        if (uniqueInstance == null) uniqueInstance = new Singleton_step2_synchronized();
        return uniqueInstance;
    }
}
  • 인스턴스를 필요할 때 생성하지 말고 JVM이 실행될 때 생성하는 방법
    • 전역 변수로 설정하는 것과 차이점은 클래스의 인스턴스를 제공할 수 없다는 점이 있다.
public class Singleton_step3_create_jvm {
    /**
     * 유일한 인스턴스를 저장하기 위한 정적 변수
     */
    private static final Singleton_step3_create_jvm uniqueInstance = new Singleton_step3_create_jvm();

    /**
     * 생성자를 private으로 선언했기 때문에 해당 클래서에서만 인스턴스를 만들 수 있다
     */
    private Singleton_step3_create_jvm() {}

    public static Singleton_step3_create_jvm getInstance() {
        return uniqueInstance;
    }
}
  • DCL(Double Checking Locking)을 통한 동기화 부하 감소 방식
public class Singleton_step4_DCL {
    /**
     * 유일한 인스턴스를 저장하기 위한 정적 변수
     * volatile을 통한 동기화 변수 선언
     */
    private volatile static Singleton_step4_DCL uniqueInstance;

    /**
     * 생성자를 private으로 선언했기 때문에 해당 클래서에서만 인스턴스를 만들 수 있다
     */
    private Singleton_step4_DCL() {}

    /**
     * synchronized 동기화 처리 -> 멀티스레드 해결
     */
    public static synchronized Singleton_step4_DCL getInstance() {
        if (uniqueInstance == null) uniqueInstance = new Singleton_step4_DCL();
        return uniqueInstance;
    }
}

좋은 웹페이지 즐겨찾기