지난주 우아한 테크코스 미션에서 멀티쓰레드(Multi Thread) 환경에서 개발했다.
싱글턴 패턴을 알고 있음에도 사용하지 않았던 것이 아쉬웠다.
간단히 정리하고 자주 보면서 기억하고 다음엔 사용해보자.

1. Singleton Pattern?


싱글턴 패턴은 오직 하나의 인스턴스만 생성해 재사용하기 위한 디자인 패턴입니다.
쉽게 말해, 생성자가 여러번 호출되더라도 해당 객체는 처음 호출할 때만 생성되고, 나머지는 처음 생성된 그 객체를 반환합니다.

2. 장단점


장점

  1. 인스턴스가 오직 한 개만 생성되므로, 메모리상 이점이 있습니다.
  2. 두 번째 호출부터는 객체 로딩 시간이 줄어 성능이 향상됩니다.
  3. 생성된 인스턴스가 전역 인스턴스이므로, 다른 인스턴스들과 데이터 공유가 쉽습니다.

단점

  1. 싱글톤으로 생성된 인스턴스가 다른 클래스의 인스턴스들과 많은 데이터를 공유할 경우 OCP원칙(Open-Closed-Principle: 개방 폐쇄 원칙)을 어기게 됩니다.

3. 어떻게 사용할까?


전역으로 그냥 생성하는 방법, DCL 기법, Enum으로 하는 방법 등 여러가지가 있지만, 현재 가장 안전성있고 많이 사용되는 방법만 소개하겠습니다.

public class Conatuseus {

  private Conatuseus(){
  }

  public static Conatuseus getInstance() {
    return LazyHolder.INSTANCE;
  }

  private static class LazyHolder{
    private static final Conatuseus INSTANCE = new Conatuseus();
  }
}

이 방법은 Thread-Safe하고, 성능도 괜찮아서 현재 가장 많이 쓰이는 방법입니다.
먼저, 코드에서 보이는 Conatuseus 객체는 외부에서 getInstance 메서드를 호출하기 전까지는 생성되지 않습니다. (따라서 이 방법은 전역으로 그냥 생성하는 방법과 인스턴스 생성 시점이 다릅니다)
getInstance 메서드가 호출되고, LazyHolder.INSTANCE를 참조하는 순간 LazyHolder 클래스가 로딩되고 초기화가 진행됩니다.