1. 일반적인 초기화(단순 메서드)
public class User {
private static User instance;
private User() {}
public static User getInstance() {
if (instance == null) {
instance = new User();
}
return instance;
}
}
- 멀티 스레드 환경에서는 인스턴스가 여러 개 생성될 수 있음
- 스레드 안전하지 않음(면접에서 단순 예시로 쓰임)
2. Synchronized 적용
public class User {
private static User instance;
private User() {}
public static synchronized User getInstance() {
if (instance == null) {
instance = new User();
}
return instance;
}
}
- 항상 메서드에 lock이 걸림
- 동시성은 보장하나, 성능 저하 문제 있음
3. 정적 멤버(즉시 초기화)
public class User {
private static final User instance = new User();
private User() {}
public static User getInstance() {
return instance;
}
}
- 클래스 로딩 시 바로 인스턴스 생성
- 인스턴스를 꼭 사용할 필요 없는데도 생성되는 문제 있음
4. 정적 블록(즉시 초기화)
public class User {
private static User instance;
static {
instance = new User();
}
private User() {}
public static User getInstance() {
return instance;
}
}
- 즉시 초기화 방식과 유사함
- 복잡한 초기화가 필요한 경우 사용
5. 정적 멤버와 Lazy Holder(중첩 클래스)
public class User {
private User() {}
private static class InstanceHolder {
private static final User INSTANCE = new User();
}
public static User getInstance() {
return InstanceHolder.INSTANCE;
}
}
- getInstance 호출 시 클래스가 로드되며 인스턴스 생성
- 스레드 안전 + Lazy Initialization + 성능
- 가장 대중적으로 많이 쓰이는 패턴
6. 이중 잠금 확인(DCL : Double-Checked Locking)
public class User {
private static volatile User instance;
private User() {}
public static User getInstance() {
if (instance == null) {
synchronized (User.class) {
if (instance == null) {
instance = new User();
}
}
}
return instance;
}
}
- 인스턴스가 없을 때만 lock 획득
- volatile로 인스턴스 동기화
- 메모리 불일치 문제 해결
- 지금은 중첩 클래스 방식이 더 많이 쓰임
7. Enum 방식
public enum UserEnum {
INSTANCE;
public void doSomething() {
// 기능 구현
}
}
- 자바에서 thread-safe 싱글톤 보장
- 이펙티브 자바에서 가장 추천하는 방식
- 직렬화/역직렬화, 리플렉션 관련 이슈까지 완벽하게 방지
결론 & Best
실무에서는 5번(중첩 클래스, Lazy Holder)과 7번(Enum 방식)이 가장 많이 쓰임
클린하면서 버그 걱정 없는 안정적인 패턴(실제로 스프링 싱글톤 빈 구현은 중첩 Holder 활용)
enum 방식은 조슈아 블로크 이펙티브 자바에서 싱글톤 구현의 최고 방법으로 언급됨
'Cs' 카테고리의 다른 글
[Cs] 팩토리 패턴 (0) | 2025.08.21 |
---|---|
[Cs] 싱글톤 패턴 (0) | 2025.08.14 |
[Cs] 라이브러리와 프레임워크 (0) | 2025.08.12 |
[Cs] 디자인 패턴이란? (0) | 2025.08.12 |
[Cs] 컴파일러와 인터프리터의 차이 (0) | 2025.08.11 |