본문 바로가기

디자인패턴

싱글톤패턴

싱글톤 패턴(Singleton Pattern)

-싱글톤 패턴은 인스턴스를 생성할때 인스턴스를 사용할때마다 새로 생성해서 사용하는것이 아니라 한번 만들어진 인스턴스를 프로그램상에서 계속 사용하도록 하는 전략이다.

-스레드풀, 캐시, 대화상자, 프린터, 사운드매니저 등등 프로그램에서 오직 하나만 생성되어야 하는 경우에 유용하다.

-공통적으로 사용하는 클래스 ex) Util Class 등에 적용한다.


구현방법1

public class Singleton { //private으로 Sinleton클래스의 유일한 인스턴스를 저장하기 위한 정적 변수를 선언 private static Singleton uniqueInstance = new Singleton(); //생성자를 private로 선언했기 때문에 Singleton에서만 클래스를 만들 수 있다. private Singleton() {}


  public static Singleton getInstance() {

return uniqueInstance; }

}


생성자와 변수가 private으로 선언되어 있기 때문에 다른 클래스내에서 Singleton.uniqueInstance = new Singleton()이 불가능하다. 때문에 인스턴스 생성은 getInstance() 메서드를 사용해서 생성하는 방법밖에 없다.

static으로 구현하면 로딩시에 Singleton인스턴스가 생성(new)되어 getInstance()메서드를 통하여 유일하게 사용할 수 있다. 하지만 큰 프로그램에서 이러한 코드가 많이 존재하게 된다면 프로그램 로딩시에 많은 인스턴스가 한꺼번에 로딩시간에 생성되기 때문에 문제가 될 수 있다.


구현방법2

public class Singleton {
  
  //private으로 Sinleton클래스의 유일한 인스턴스를 저장하기 위한 정적 변수를 선언
  private static Singleton uniqueInstance;

  //생성자를 private로 선언했기 때문에 Singleton에서만 클래스를 만들 수 있다.
  private Singleton() {}

  //클래스의 인스턴스를 만들어서 리턴해 준다.
  public static Singleton getInstance() {
    if(uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
    return uniqueInstance;
  }

}

new하는 부분을 getInstance()안에 담아서 최초사용 시점에 null이기 때문에 생성하고 그 이후로는 이미 생성한 인스턴스를 계속 사용하게끔 하는 방법이다. 

하지만 멀티 스레드상에서 getInstance()메서드를 동일 시점에 호출하면 인스턴스가 두개가 생길 가능성이 있다.


구현방법3

public class Singleton {
  
  //private으로 Sinleton클래스의 유일한 인스턴스를 저장하기 위한 정적 변수를 선언
  private static Singleton uniqueInstance;

  //생성자를 private로 선언했기 때문에 Singleton에서만 클래스를 만들 수 있다.
  private Singleton() {}

  //클래스의 인스턴스를 만들어서 리턴해 준다.
  public static synchronized Singleton getInstance() {
    if(uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
    return uniqueInstance;
  }

}
자바 synchronized 키워드를 사용하여  getInstance()메서드를 동기화 시켜주었다. 이렇게 하면 동시에 접근하여 사용하는 것은 방지할 수 있지만, 다수의 쓰레드가 이 메서드를 호출하게 되면 오버헤드가 매우 커지므로 synchronized는 반드시 꼭 필요한 부분에만 구현해야한다.