싱글톤 패턴
🙉

싱글톤 패턴

Created
Apr 12, 2024 04:02 AM
Last edited time
Last updated April 12, 2024
Tags
CS
Language
Java
URL

Intro::

싱글톤 패턴에 대해 알아봅시다.
 

싱글톤 패턴이란?

💡
하나의 인스턴스만 생성하여 사용하는 디자인 패턴이다.
싱글톤으로 구현한 인스턴스는 전역이므로, 다른 클래스의 인스턴스들이 데이터를 공유하는 것이 가능한 장점이 있다.
 

주요 적용 상황

주로 공통된 객체를 여러개 생생해서 사용해야 하는 상황, 또한 인스턴스가 절대적으로 한 개만 존재하는 것을 보증하고 싶을 때 사용.
  • 데이터 베이스에서 커넥션 풀
  • 스레드 풀
  • 캐시
  • 로그 기록 객체
 

단점

  • 싱글톤 인스턴스가 너무 많은 책임을 가지거나, 데이터를 너무 많이 공유해 결합도가 높아진다면, 개방-폐쇄 원칙을 위배하게 됩니다.
  • 결합도가 높아지면 유지보수가 어려워집니다.
  • 멀티 스레드 환경에서 동기화 처리를 하지 않았을 때, 인스턴스가 2개 발생하는 문제가 생길 수 도 있습니다.
 

멀티스레드 환경에서 안전한 싱글톤

  1. Lazy Initialization
    1. public class ThreadSafe_Lazy_Initialization { private static ThreadSafe_Lazy_Initialization instance; private ThreadSafe_Lazy_Initialization() {} public static synchronized ThreadSafe_Lazy_Initialization getInstance() { if (instance == null) { instance = new ThreadSafe_Lazy_Initialization(); } return instance; } }
      private static으로 인스턴스 변수 생성
      private으로 생성자를 만들어 외부에서의 생성을 막음
      synchronized 동기화를 활용해 스레드를 안전하게 만듬 (큰 성능저하를 발생하므로 권장하지 않습니다.)
  1. Lazy Initialization + Double-checked Locking
    1. 1번의 성능저하 개선
      public class ThreadSafe_Lazy_Initialization { private volatile static ThreadSafe_Lazy_Initialization instance; private ThreadSafe_Lazy_Initialization() {} public static ThreadSafe_Lazy_Initialization getInstance() { if (instance == null) { synchronized (ThreadSafe_Lazy_Initialization.class) { if (instance == null) { instance = new ThreadSafe_Lazy_Initialization(); } } } return instance; } }
  1. Initialization on demand holder idiom (holder에 의한 초기화)
    1. 클래스 안에 클래스를 두어 JVM의 클래스 로더 매커니즘과 클래스가 로드되는 시점을 이용한 방법
      💡
      실제로 가장 많이 사용하는 일반적인 방법
      public class Singleton { private Singleton() { } private static class LazyHolder { public static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return LazyHolder.INSTANCE; } }
      JVM의 클래스 초기화 과정에서 보장되는 원자적 특성을 이용해 싱글톤의 초기화 문제에 대한 책임을 JVM에 떠넘기는 것을 활용합니다.
      클래스 안에 선언한 클래스인 holder에서 선언된 인스턴스는 static이기 때문에 클래스 로딩시점에서 한번만 호출됩니다. 또한 final을 사용해서 다시 값이 할당되지 않도록 만드는 방식을 사용한 것입니다.

References::

Loading Comments...