Effective Java에서는 SingleTon 패턴을 위해 Enum을 활용하는 것을 제안하기도 하지만,
Context 라는 개념이 있는 Android에서는 적합하지 않다.
Singleton의 초기화 과정에 context의 의존성이 끼어들 여지가 있기때문이다.
결론적으로 Android Singleton 패턴을 사용하고자 한다면 LazyHolder 기법을 사용하자.
기본 코드
public class Singleton {
private Singleton() {}
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
}
객체를 사용하고자 할 때 초기화를 미루는(lazy) 것.
Singleton 클래스에는 LazyHolder 클래스의 변수가 없으므로, Sinlgeton 클래스 로딩 시에
LazyHolder 클래스를 초기화하지 않음. LazyHolder 클래스는 Singleton 클래스의 getInstance()에서
LazyHolder.INSTANCE 를 참조하는 순간 class가 로딩되며 초기화가 진행.
Class를 로딩하고 초기화하는 시점을 code를 작성한 프로그래머가 아닌, system(framework)에 맡기는 것이므로
thread-safe 할 수 있다고 볼 수 있다. 그러므로 volatile, synchronized 키워드없이 thread-safe 하면서도 성능이
보장된 기법. (synchronized 키워드를 사용하면 성능이 많이 떨어지는 것으로 알려져있다.)
다른 글(memoery leak을 피하는 방법)에도 나오지만,
inner class(여기서는 LazyHolder class)를 static으로 생성하면,
outer class(여기서는 Singleton class)에 대해 의존성 reference를 갖지않는다.