Singleton Pattern

윤세영·2023년 7월 6일
0

DesignPattern

목록 보기
10/15

정의

  • Singleton Pattern은 해당 Class의 instance가 하나만 만들어진다.
  • 어디서든 그 instance에 접근할 수 있게 한다.
  • class에서 하나뿐인 instance를 관리하게 한다.
  • Instance가 사용될 때 똑 같은 instance를 만드는 것이 아닌, 동일 instance를 사용하게끔 하는 것이다.
고전적인 Singleton Pattern
public class Singleton {
  private static Singleton uniqueInstance;
  private Singleton(){}
  public static Singleton getInstance() {
    if(uniqueInstance == null){
      uniqueInstance = new Singleton();
    }
  return uniqueInstance;
  }
} 
  • 전역변수로 instance를 생성하는데 private static 키워드를 사용한다.
  • Static이 붙은 class 변수는, 인스턴스화에 상관없이 사용할 수 있다.
  • 하지만, private 접근 제어자로 인해
Singleton.uniqueInstance
  • 와 같은 방법으로 접근할 수 없다.
  • 이 상태에서 private 키워드를 붙이는데 그러면 new 키워드를 사용할 수 없게 된다.
  • 그 결과 외부 class가 위 class의 instance를 가질 수 있는 방법은, getinstance() method를 사용하는 방법밖에 없다.
  • 하지만 위의 방법은 Multi-threading과 관련해서 문제가 생긴다.
  • 그 이유는 thread로 getinstance() method를 호출하면 instance가 두 번 생길 수 있기 때문이다.
  • 이러한 문제를 방지하기 위해, getinstance() method를 동기화 시킨다.
public class Singleton {
  private static Singleton uniqueInstance;     // 기타 인스턴스 변수
  private Singleton() {}     //synchronized 키워드만 추가하면      // 두 스레드가 이 메소드를 동시에 실행시키는 일은 일어나지 않게 된다.
  public static synchronized Singleton getInstance() {
    if (uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
  return uniqueInstance;
  }
}
  • 위와 같이 할 수 있는데 이 방법도 문제가 있다. 수 많은 thread들이 getinstance() method를 호출하기 위해 동기화 하면 성능이 떨어진다.
  • 이러한 문제를 방지하기 위해서 instance를 필요할 때 생성하는 것이 아니라, 처음부터 생성하는 방법이 있다.
public class Singleton {
  private static Singleton uniqueInstance = new Singleton();
  private Singleton() {}
  public static Singleton getInstance() {
    return uniqueInstance;
  }
}
  • 위와 같이 하는 방법 외에도 DCL(Double-Checking Locking)을 사용하여 getinstance()에서 동기화되는 부분을 줄이는 방법이 있다.
  • DCL을 사용하면 instance가 생성되어 있는지 확인한 후, 생성이 되어있지 않을 때만 동기화를 할 수 있다.
  • Volatile 키워드를 사용해서 multi-threading을 사용하더라도, 변수가 Singleton instance로 초기화 되는 과정이 올바르게 할 수 있다.
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();
      }
    }
  }
  return uniqueInstance;
}
profile
Frontend

0개의 댓글