Singleton pattern : getInstance()
1. 기본 개념과 형식
public class Singleton {
private Singleton() {
}
private static Singleton sInstance;
public static Singleton getInstance() {
if (sInstance == null) {
sInstance = new Singleton();
}
return sInstance;
}
}
- 어디든 누구든 getInstance() 를 호출하면 항상 같은 Instance를 줘야 한다는 개념이다.
- getter의 명칭 또한 똑같이 쓰기 때문에 구현방식에 대한 포멧같은 느낌
2. 동기화 문제
- 위 코드는 멀티 Thread 상황에서 A Thread가 instance 생성하고 저장하지 않은 시점에 B Thread가 생성하고 저장하고 나갈 수 있는 경우가 생긴다.
이를 해결하는 방안으로
1) Synchronized를 method에 걸어서 해결
2) static block으로 생성하여 해결
3) Lazy Holder class 이용하여 해결
4) Enum class 로 만들어 해결
이 있다.
2-1. Synchronized를 method에 걸어서 해결
public class Singleton {
private Singleton() {
}
private static Singleton sInstanceSync;
public static synchronized Singleton getInstanceSync() {
if (sInstanceSync == null) {
sInstanceSync = new Singleton();
}
return sInstanceSync;
}
}
- (차이설명을 위해 명칭을 변경함)
- 말 그대로 synchronized를 걸면 된다.
- 장점: Lazy initialize 가능, Thread safe
- 단점: synchronized의 비용이 비싸다. 즉, 매번 오래걸린다.
2-2. static block으로 생성하여 해결
public class Singleton {
private Singleton() {
}
private static final Singleton STATIC_INSTANCE = new Singleton();
public static Singleton getInstanceStatic() {
return STATIC_INSTANCE;
}
}
- class load되는 시점에 static이 실행되며 객체도 생성된다.
- 장점: Thread safe
- 단점: 필요한 상황에 만들어지는 것은 아니다. 즉, 미리 만들어져 있다.
2-3. Lazy Holder class 이용하여 해결 (좀 더 정확한 명칭은 Initialization-on-demand holder idiom)
public class Singleton {
private Singleton() {
}
private static class LazyHolder {
public static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstanceLazyHolder() {
return LazyHolder.INSTANCE;
}
}
- static block과 유사하지만 내부 클래스가 로딩되는 시점에 static이 실행된다.
- 장점: Lazy initialize 가능, Thread safe
- 많이 쓰는 편이라고 한다.
2-4. Enum class 로 만들어 해결
public enum SingletonEnum {
INSTANCE;
// TODO: your methods
}
- Enum에 메소드를 다는 방식
- 장점: Lazy initialize 가능, Thread safe
- Effective Java 2/E에 나온 방법
3. Singleton instance를 Reflection으로 생성한다면 이 모든 노력은 무용지물
- private 으로 생성자를 막아도 생성이 가능하기 때문
이 내용에 대한 코드는 Github에서도 확인하실 수 있습니다.
- https://github.com/ndukwon/Duk_Java_library/tree/master/src/com/duk/lab/java/pattern
Reference
- http://jusungpark.tistory.com/16
- https://blog.seotory.com/post/2016/03/java-singleton-pattern
- http://changsuk.me/?p=1433
- https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom