클래스가 오직 하나의 객체만 가지도록 함.
객체 하나 생성시 많은 자원을 필요로 하는 경우 이 패턴을 사용.
static method구현| 초기화 방식 | Lazy Initialization | Thread-Safe | 설명 |
|---|---|---|---|
| Eager Initialization | 아니요 | 예 | 클래스 로드 시점에 인스턴스를 생성합니다. |
| Simple Locking | 예 | 예 | 인스턴스 생성 시 항상 동기화 블록을 사용합니다. |
| Double-Checked Locking | 예 | 예 | 인스턴스가 존재하는 경우 동기화 블록을 건너뛰어 성능을 최적화합니다. |
*Lazy Initialization = 인스턴스가 실제로 필요할 때까지 생성되지 않는 방식
단일 스레드 환경: 단일 스레드 환경에서는 동기화 없이도 안전하게 싱글턴을 생성할 수 있습니다.
간단한 구현: 코드가 비교적 간단하며, 동기화에 따른 성능 저하가 없습니다.
public class Singleton
{
private Singleton() {}
private static Singleton uniqueInstance;
public static Singleton getInstance()
{
synchronized(Singleton.class) {
if (uniqueInstance == null)
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
멀티스레드 환경에서 안전하지 않음: 동기화를 하지 않기 때문에, 멀티스레드 환경에서는 여러 스레드가 동시에 인스턴스를 생성하려 할 수 있습니다.
멀티스레드 환경에서 안전함: 두 번의 체크와 동기화를 통해 인스턴스가 동시에 여러 번 생성되는 것을 방지합니다.
성능 최적화: 필요할 때만 동기화를 사용하여 성능 저하를 최소화합니다.
public class Singleton2
{
private Singleton2() {}
private volatile static Singleton2 uniqueInstance;
public static Singleton2 getInstance()
{
if (uniqueInstance == null) { // single checked
synchronized(Singleton2.class) {
if (uniqueInstance == null) // double checked
uniqueInstance = new Singleton();
}
}
return uniqueInstance;
}
}
volatile키워드 사용멀티스레드 환경에서 안전함: 클래스가 로드될 때 인스턴스가 생성되므로 동기화가 필요 없습니다.
간단하고 직관적: 구현이 매우 간단하며, 성능 문제가 없습니다.
public class Singleton
{
private Singleton() {}
private static Singleton uniqueInstance = new Singleton();
public static Singleton getInstance()
{
return uniqueInstance;
}
}
지연 초기화 불가: 클래스 로딩 시점에 인스턴스가 생성되기 때문에, 사용하지 않더라도 메모리를 차지합니다.
즉 위의 예시에서 Singleton.getInstance()가 실행될 때 인스턴스가 생성된다
i) 인스턴스 생성이 복잡하지 않거나 리소스를 많이 소모하지 않는 경우에 적합
ii) application이 실행될 때 항상 인스턴스가 필요한 경우