-
[Design Pattern] Singleton PatternLearn/Architecture 2022. 8. 31. 00:38
# 개요
인스턴스가 단 하나만 만들어지게 하고싶을 때 사용하는 패턴
(예시) Thread Pool Manager은 여러개면 그들간의 조율이 필요하므로 하나만 있는게 좋다.
싱글톤은 new로 인스턴스를 생성하는게 아니라 getInstance 함수로 얻는다.
# 기본 구조
- 일반적인 생성자와는 달리 접근하지 못하도록 private로 생성자를 만든다.
- 생성자를 만들지 않으면 자바가 알아서 public으로 생성하므로 꼭 만들어줘야한다.
- 외부에서는 getInstance를 통해서만 인스턴스를 얻을 수 있다.
- 외부에서 이 함수에 바로 접근할 수 있게 static으로 선언해야 한다.
- 생성자를 대신하므로 public으로 열어줘야 한다.
- uniqueInstance는 클래스에 단 하나만 있어야 하므로 static으로 만든다.
- 외부에서 마음대로 조작하지 못하게 private로 만든다.
public class Singleton { private static Singleton uniqueInstance; // other useful instance variables private Singleton() {} public static Singleton getInstance() { // 한번만 생성되도록 함 if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } // other useful methods }
# Singleton on Multi-threads
싱글톤은 멀티 쓰레드에서 잘 작동하지 않는다.
- 아래와 같이 타이밍이 엇갈리면 제대로 작동하지 않는다.
해결책 1
getInstance 함수에 synchronized 키워드를 붙여준다.
- synchronized 함수는 하나의 쓰레드에서 사용되면 lock이 걸린다.
잘 동작하지만 문제는 이렇게 작성하면 성능에 영향을 준다.
- 두 번째 쓰레드부터는 딱히 필요가 없다.
해결책 2
아래와 같이 uniqueInstance를 선언해줄 때 인스턴스를 만들어준다.
성능 문제는 해결되지만 무조건 인스턴스를 만들기 때문에 메모리 사용 측면에서는 좋지 않다.
public class Singleton { private static Singleton uniqueInstance = new Singleton(); // other useful instance variables private Singleton() {} public static Singleton getInstance() { return uniqueInstance; } // other useful methods }
해결책 3
자바 1.5부터 volatile이라는 키워드를 제공한다.
그리고 getInstance에서는 double-checked locking을 적용한다.
public class Singleton { private volatile static Singleton uniqueInstance = null; // other useful instance variables private Singleton() {} public static Singleton getInstance() { if (uniqueInstance == null) { synchronized(Singleton.class) { if (uniqueInstance == null) uniqueInstance = new Singleton(); } } return uniqueInstance; } // other useful methods }
# QUIZ
SingletonA 클래스와 SingletonB 클래스가 각각 싱글톤 패턴으로 구현되었다고 가정할 때, 다음 코드의 수행결과를 쓰시오.
정답
각 클래스별로 같은게 나오므로 1, 2가 출력된다.
'Learn > Architecture' 카테고리의 다른 글
[Design Pattern] Decorator Pattern (0) 2022.09.24 [Design Pattern] Adapter Pattern (0) 2022.09.04 [Design Pattern] Builder Pattern (0) 2022.08.30 [Design Pattern] Factory Method & Abstract Factory Patterns (0) 2022.08.29 [Design Pattern] Mediator Pattern (0) 2022.08.29 - 일반적인 생성자와는 달리 접근하지 못하도록 private로 생성자를 만든다.