싱글톤 패턴 구현 방법은 크게 두 가지로 나뉘는데,
1. 메모리가 올라올 때 생성하는 방법
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
2. 객체가 호출될 때 생성하는 방법
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
이 때 각 코드 두 번째 라인을 눈여겨 보면,
하나는 참조변수에 객체가 생성되는 부분까지 선언되어 있고,
private static Singleton instance = new Singleton();
나머지는 참조변수만 선언되어 있다.
private static Singleton instance;
이 구현방법 차이로 하나는 프로그램이 시작되면서 메모리가 올라올 때 바로 인스턴스화 되고,
나머지 하나는 참조변수만 선언되어 있다가, 호출될 때(여기선 getInstance) 인스턴스화 된다.
당연히 호출할 때 인스턴스화 되는 쪽이 메모리를 덜 잡아먹고 이를 우리는 "Lazy Initialization"이라고 한다.
<추가>
lazy initialization은 호출시 생성된다는 구현의 특성때문에, 싱글톤의 원칙(하나의 객체만 생성되어야 함)을 지키기 위해 조건문이 한 줄 더 추가된다.
if (instance == null) {
instance = new Singleton();
}
그게 바로 이 부분인데,
이 코드가 없다면 멀티스레드 환경에서 동기화 여부에 따라 여러개의 객체가 만들어지거나 아니면 무한 가비지를 생성하는 문제점을 낳을 수 있다.