✍️ 멀티 쓰레드에서 안전하지 않은 Singleton
Thread A가 if의 조건을 통과하고 new를 하기 전에 Thread B가 if문을 검사한다면 Thread A와 B 모두 인스턴스를 생성하게 된다.
🍊 멀티 쓰레드에서 안전한 싱글톤 패턴
1, synchronized
synchronized 키워드를 사용해서 메서드를 동기화하는 방법으로, 한 번에 하나의 쓰레드만 메서드를 통과하게 된다.
public static synchronized Settings getInstance() {
if (instance == null) {
instance = new Settings();
}
return instance;
}
간단하고 쉬운 방법이지만 단점으로 동기화 처리로 인해 성능의 이슈가 생길 수 있다. 동기화 메커니즘은 lock을 잡고 푸는 일련의 행위로 비용이 발생하므로 적절한 trade-off를 계산해서 사용하는 것이 바람직하다.
2, 이른 초기화 (eager initialization)
만약에 객체를 나중에 만들지 않아도 되며 객체를 생성하는 비용이 비싸지 않다면 미리 만들 수 있다.
싱글톤 인스턴스는 클래스가 로딩되는 시점에 초기화되므로 멀티 쓰레드에서도 안전하다. 다만 단점은 인스턴스를 미리 만든다는 것 자체가 단점이 될 수 있다. 인스턴스를 만드는 과정이 오래 걸리고 자원을 많이 소모하고 극단적으로 사용되지 않는다면 불필요한 자원 소모가 될 수 있다.
public class Settings {
private static final Settings INSTANCE = new Settings();
private Settings() {
}
public static Settings getInstance() {
return INSTANCE;
}
}
3, static inner 클래스 사용하기
멀티 쓰레드 환경에서 안전하고 getInstance가 호출될 때 SettingsHolder class가 로딩되므로 객체를 lazy하게 생성하는 장점을 가지고 있다.
public class Settings {
private Settings() {
}
private static class SettingsHolder {
private static final Settings INSTANCE = new Settings();
}
public static Settings getInstance() {
return SettingsHolder.INSTANCE;
}
}
⚠️ 완전히 안전한 싱글톤 생성 방법일까?
static inner 클래스는 권장하는 싱글톤 생성 방법 중 하나이다. 하지만 지금까지 살펴봤던 모든 방법을 깨트리는 다양한 코딩 방법들이 존재한다.
'Java > Design Pattern with Java' 카테고리의 다른 글
[객체 생성 패턴] Chapter 2-1. Factory Method Pattern : 패턴 소개 (0) | 2022.03.31 |
---|---|
[객체 생성 패턴] Chapter 1-5. Singleton Pattern : 자바에서 찾아보는 싱글톤 (0) | 2022.03.28 |
[객체 생성 패턴] Chapter 1-4. Singleton Pattern : 안전하고 단순한 싱글톤 (0) | 2022.03.28 |
[객체 생성 패턴] Chapter 1-3. Singleton Pattern : 싱글톤을 깨트리는 방법 (0) | 2022.03.28 |
[객체 생성 패턴] Chapter 1-1. Singleton Pattern : 가장 단순한 구현 (0) | 2022.03.28 |