싱글톤을 구성하는 방식은 여러 가지가 있습니다.
public class SingletonExample {
private static final INSTANCE = new SingletonExample();
private SingletonExample(){
}
public static SingletonExample getInstance() {
return INSTANCE;
}
}
가장 간단한 구조부터, Lazy Loading과 Thread Safe를 지키기 위한 구조도 있습니다.
public class SingletonExample {
private SingletonExample(){
}
private static class LazyHolder {
private static final SingletonExample INSTANCE = new SingletonExample();
}
public static SingletonExample getInstance() {
return LazyHolder.INSTANCE;
}
}
여러 구조 중 가장 성능이 좋다고 평가받는 형태입니다(인스턴스의 생성을 getInstance()
가 호출되었을 때 코드의 로직이 아닌 JVM 동적 로드를 사용). 레이지 홀더 싱글톤이라고 부릅니다.
기존의 싱글톤 인스턴스를 내부 정적 클래스에 올려, 싱글톤 클래스 자체를 사용하더라도 getInstance()
메서드를 호출하지 않는 이상 인스턴스는 만들어지지 않습니다.
static으로 정의되어있는 만큼, 여러 스레드가 한 번에 인스턴스 획득을 요구하더라도 단 한번만 생성됩니다.
다만, 과연 이 구조가 실질적으로 필요한가에 대한 의구심이 생겼습니다.
JVM은 애플리케이션이 동작될 때 모든 클래스를 메모리에 적재하지는 않습니다. 컴파일러에 의해 생성된 바이트코드(.class)를 클래스 로더를 통해 불러옵니다. 클래스 로더는 바이트코드를 읽고 해당 클래스를 로드합니다.
클래스가 로드되는 경우는 다음과 같습니다.
싱글톤의 입장에서 로드되는 경우를 살펴보겠습니다.
그러나, 위에서 작성했듯 코드의 방향성에 대해 다시금 판단해봐야 할 인자들로 판단됩니다.