Contents

디자인패턴-싱글톤

디자인 패턴중에 가장 잘 알려진 싱글톤 에 대해서 알아보고자 한다. 멀티 스레드 환경에서 자주 이용되는 패턴이라고만 들었는데 이번 기회를 통해 제대로 정리해보자

싱글톤이 무엇인가

싱글톤(Singleton)은 정확히 하나의 인스턴스만 생성되는 클래스이다.

라고 이펙티브 자바에서 정의되어있다. 즉, 딱 하나만 생성하고 이를 여기저기서 사용하는 패턴이라 생각하면 될듯 하다. 싱글 스레드 환경에서는 당연히 인스턴스를 공유할 상황이 없겠지만 대부분 멀티 스레드 환경이기 때문에 싱글톤 패턴은 아주 중요한 부분이다.

아주 고전적인 방법 (위험한 방법)

public class Singleton {
	private static Singleton uniqueInstance;

	private Singleton(){}

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

위와 같은 상황에서 if절을 도달하는 시점이 각 스레드마다 다를경우 문제가 발생할 수 있다.(교묘한 시점에 객체가 1개 이상 반환될 여지가 있음) 이를 해결하기 위해서는 다음과 같이 getInstance()를 동기화 해주면 된다. 하지만 불필요하게 동기화 하는 오버헤드만 증가하게 된다.

public class Singleton {
 private static Singleton uniqueInstance;

 private Singleton(){}

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

public static 인스턴스로 생성

 public static final LocalCache sharedObject = new LocalCache();

 private LocalCache()
 {
 }

이코드는 간단하다는 장점이 있는 반면에 유연하지 못한 부분이 있다. (아래 이어서 설명)

private static final 인스턴스로 생성

private static final LocalCache sharedObject = new LocalCache();

 private LocalCache()
 {
 }

 public static LocalCache getInstance()
 {
     return sharedObject ;
 }

이렇게 하면 factory 메소드를 통해 객체를 반환받고, 반환 받는 시점에 다양한 작업들을 할수 있다.

enum 으로 생성

public enum LocalCacheEnum
{
    LocalCache;

    //etc another functions
}

잘 사용하지는 않지만 가장 좋은 세번째 방법인 enum으로 클래스를 만드는 방법이라고 한다. 복잡한 직렬화나 리플렉션(reflection) 상황에서도 직렬화가 자동으로 지원되고, 인스턴스가 여러개 생기지 않도록 확실하게 보장해준단다. (by effective java)

그럼 어디서 사용될까

  1. static 으로 선언해서 공통적으로 사용되는 부분이나 환경설정
  2. 내용이 변경되면 다른 클래스에서도 그 부분이 똑같이 적용되어 실행되어야 할때
  3. 자주 사용되는 부분을 싱글톤으로 만들어 생성되는 시간을 줄일때
  4. 스프링에서의 DB커넥션 로직

Buy me a coffeeBuy me a coffee