지식/디자인패턴
Head First Design Patterns : Singleton Pattern
by CodeRain
2024. 1. 1.
Singleton Pattern
- 클래스 인스턴스가 하나만 있도록 하면서 이 인스턴스에 대한 전역 접근 지점을 제공
구조
Singleton Pattern 구조
- 정적 메서드 getInstance 선언. 선언된 클래스의 인스턴스 반환
- 생성자는 숨겨져 있어야함. 인스턴스를 가져오는 방법은 getInstance가 유일.
public class Singleton {
private static Singleton instance;
private Singleton() {}
public Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance
}
}
- 고전적인 Singleton 구현
- multi thread 환경에서 여러개의 인스턴스가 생길 가능 성이 있음
public class Singleton {
private static Singleton instance;
private Singleton() {}
public syncronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance
}
}
- syncronized 키워드로 동기화
- 동기화 시 성능 저하
public class Singleton {
private static Singleton instance = new Singleton;
private Singleton() {}
public Singleton getInstance() {
return instance
}
}
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public syncronized Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null {
instance = new Singleton();
}
}
}
return instance
}
}
- Double-Checked Locking 을 사용하여 생성 되지 않았을 경우만 동기화 사용.
- volatile 키워드 사용하여 multi thead 환경에서 올바르게 초기화 됨.
# volatile 이란?
- 해당 키워드가 붙은 변수 값이 메인 메모리에 저장.
- 멀티 쓰레드 환경에서 메인 메모리의 값을 참조하므로 변수 값 불일치 문제를 해결.
- 하나의 thread에서 읽고 쓰고, 다른 쓰레드에서는 읽기만 할 때 적합
https://nesoy.github.io/articles/2018-06/Java-volatile
장점
- 클래스가 하나의 인스턴스만 갖음.
- 처음 요청 시에만 초기화 됨.
단점
- SRP 위배
- Multi Thread 환경에서 처리 필요
예
- 많은 개발자들이 안티패턴으로 간주. 자바 코드에서의 사용 감소하고 있으나 여전히 코어에서 사용됨.
- java.lang.Runtime#getRuntime()
- java.awt.Desktop#getDesktop()
- java.lang.System#getSecurityManager()
참조