PIDGEY
PIDGEY's Dev. BLOG
PIDGEY
전체 방문자
오늘
어제
  • 분류 전체보기 (30)
    • 개발 (28)
      • Java (6)
      • Spring Framework (4)
      • Design Pattern (7)
      • CS (0)
      • Algorithm (8)
      • React.JS (2)
    • 일기 (2)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

hELLO · Designed By 정상우.
PIDGEY

PIDGEY's Dev. BLOG

개발/Design Pattern

[Design Pattern] 싱글톤 패턴 (Singleton)

2022. 10. 19. 20:10

Singleton Pattern

Singleton Pattern은 클래스의 인스턴스가 하나이면서 해당 인스턴스에 대해 전역적으로 접근할 수 있도록 하는 디자인 패턴입니다.
설정이나 관리를 위한 어떠한 역할을 수행하는 인스턴스가 단 하나만 존재해서 관리하도록 하는 등에 사용됩니다.

장점

  • 클래스에 인스턴스가 하나만 있음을 확인, 보증할 수 있습니다.
  • 다른 클래스의 인스턴스들이 싱글톤 인스턴스에 접근하기 쉽습니다. 
  • 메모리 영역에 할당되는 인스턴스가 하나이므로 *메모리를 낭비하지 않을 수 있습니다.

단점

  • 싱글톤 인스턴스가 전역적인 접근을 처리하다 보면 다른 클래스 인스턴스와 결합도가 높아져 단일 책임 원칙을 위반할 수 있습니다.
  • 멀티 쓰레드 환경에서 동기화 처리를 하지 않을 경우 다중 인스턴스가 생성되는 등의 문제가 발생할 수 있습니다.
  • 많은 테스트 프레임워크가 객체를 생성할 때 상속에 의존하기 때문에 싱글톤 인스턴스의 단위 테스트에 어려움이 있을 수 있습니다.

구현 방법

  1. 싱글톤 인스턴스를 저장하기 위한 private static 필드를 추가합니다.
  2. 싱글톤 인스턴스를 반환하기 위한 public static 메소드를 추가합니다.
    • 인스턴스를 반환하기 전 필드가 null 인지 체크하여 없으면 생성해서 넣어주고, 있으면 기존 인스턴스를 반환합니다.
  3. 생성자를 private로 만듭니다.
  4. 단일 쓰레드, 멀티 쓰레드 등에 맞게 적용합니다.

기본 예제

Lazy Initialization 방법의 예제입니다.

public class Singleton {
	private static Singleton instance;

	private Singleton() {
		// ...
	}

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

메소드 동기화

멀티 쓰레드 환경에서 Critical Section으로 인해 인스턴스가 중복 생성될 수 있는 것을 방지해보자 !

public class Singleton {
	private static Singleton instance;

	private Singleton() {
		// ...
	}

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

중복 생성은 막았지만 메소드 호출이 동기화되는 경우 성능에 영향을 미칠 수 있습니다.

Double-Checked Locking Pattern (DCLP)

메소드에 동기화를 하지 않고 인스턴스가 없을 때 생성하는 부분만 동기화를 걸어주면 조금 더 효율적으로 동작하겠죠?

public class Singleton {
	private static volatile Singleton instance;

	private Singleton() {
		// ...
	}

	public static Singleton getInstance() {
		if (instance == null) {
			synchronized(Singleton.class) {
				if (instance == null) {
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

처음 생성할 때 말고는 synchronized에 걸리지 않기 때문에 성능이 조금 더 개선됐습니다 🔥
그러나 동기화 문제에 대한 코드가 추가되면서 복잡도가 올라갈 수 있죠.

Bill Pugh Solution

Bill Pugh(윌리엄 퓨) Singleton, Static Holder Singleton Pattern, Initialization-on-demand Holder Idiom라고 불립니다.
이름에서 알 수 있듯이 Holder라는 개념이 등장합니다. 이는 클래스 안의 클래스입니다.
이 방법은 JVM의 클래스 초기화 특성을 활용하여 Thread Safe가 보장되도록 합니다.

public class Singleton {
	private Singleton() {
		// ...
	}

	private static class SingletonHolder {
		public static final Singleton INSTANCE = new Singleton();
	}

	public static Singleton getInstance() {
		return SingletonHolder.INSTANCE;
	}
}

참고

Initialization-on-demand holder idiom

refactoring.guru

저작자표시 비영리 동일조건 (새창열림)

'개발 > Design Pattern' 카테고리의 다른 글

[Design Pattern] 추상 팩토리 패턴 (Abstract Factory)  (0) 2022.10.26
[Design Pattern] 팩토리 메서드 패턴 (Factory Method)  (0) 2022.10.25
[Design Pattern] 어댑터 패턴 (Adapter)  (0) 2022.10.24
[Design Pattern] 데코레이터 패턴 (Decorator)  (0) 2022.10.24
[Design Pattern] 프록시 패턴 (Proxy)  (0) 2022.10.20
    '개발/Design Pattern' 카테고리의 다른 글
    • [Design Pattern] 팩토리 메서드 패턴 (Factory Method)
    • [Design Pattern] 어댑터 패턴 (Adapter)
    • [Design Pattern] 데코레이터 패턴 (Decorator)
    • [Design Pattern] 프록시 패턴 (Proxy)
    PIDGEY
    PIDGEY

    티스토리툴바