To Be Developer

[Design Pattern] Singleton Pattern (싱글톤 패턴) 본문

Design Pattern

[Design Pattern] Singleton Pattern (싱글톤 패턴)

Jeff Hwang 2019. 4. 22. 16:57

Singleton Pattern

  • 인스턴스가 하나 뿐인 객체를 만들 수 있게 해 주는 패턴
  • 어디서든지 그 인스턴스에 접근할 수 있도록 하기 위한 패턴

Little Singleton

public MyClass{
    // 생성자가 private로 선언되어 있기 때문에 인스턴스를 만들 수 없다.
    private MyClass(){}

    // return 타입이 MyClass인 getInstance 라는 명인 정적 메서드
    // 그렇기에 생성자가 private로 선언되어있어도 인스턴스를 만들 수 있게 되었다.
    // 호출하는 방법은 MyClass.getInstance();
    public static MyClass getInstance(){
        return new MyClass();
    }
    // getInstance는 정적 메소드 or 클래스 메소드라고도 불림

}

멀티스레딩 문제해결 방법

public class Singleton {
    private static Singleton uniqueInstance;
    // 기타 인스턴스 변수

    private Singleton() {}

    // 정적인 동기식 메서드
    public static synchronized Singleton getInstance() {
        if(uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

    // 기타 메서드
}
  • 멀티스레드를 이용하면 충돌이 날 확률이 높아지는데 동기화 를 이용해 해결할 수 있다.
    • 그러나 동기화를 사용하면 쓸데없이 오버헤드만 증가시킬 뿐이다.

더 효율적인 방법

  1. getInstance()의 속도가 중요하지 않다면 그냥 둔다

  2. 인스턴스를 필요할 떄 생성하지 말고, 처음부터 생성

    public class Singleton {
        // 처음부터 생성
        private static Singleton uniqueInstance = new Singleton();
        private Singleton() {}
    
        public static Singleton getInstance(){
            return uniqueInstance;
        }
    }
    • JVM에서 유일한 인스턴스를 생성하기 전에는 그 어떤 스레드도 uniqueInstance 정적 변수에 접근이 불가능
  3. DCL(Double-Checking Locking) 을 사용해서 getInstance()에서 동기화되는 부분을 줄임

    • DCL 을 사용하면, 일단 인스턴스가 생성되어 있는지 확인한 다음, 생성되어 있지 않았을 때만 동기화를 할 수 있다.
    • DCL 을 사용하면 처음 한 번만 동기화를 하고 그 후에는 동기화를 하지 않아도 됨
    public class Singleton{
       private volatile static Singleton uniqueInstance;
    
       private Singleton(){};
    
       public static Singleton getInstance(){
           if(uniqueInstance == null) {
               synchronized (Singleton.class) {
                   if (uniqueInstance == null) {
                       uniqueInstance = new Singleton();
                   }
               }
           }
       }
    }
    • getInstance 메소드를 사용할 때 속도가 문제가 될 수있다면 이런 식으로 Singleton을 구현하여 오버헤드를 줄일 수 있다.

[참조] - Head First Design Pattern - O'REILLY (한빛미디어)

'Design Pattern' 카테고리의 다른 글

[Design Pattern] Observer Pattern (옵저버 패턴)  (0) 2019.04.20