반응형
싱글톤(Singleton) 패턴은 자바에서 가장 많이 사용되는 디자인 패턴 중 하나다.
한 번쯤은 "인스턴스를 하나만 만들고 싶다"라는 생각을 해봤다면, 싱글톤을 이미 직간접적으로 써봤을 수도 있다.
이 글에서는 싱글톤 패턴이 무엇이고, 왜 쓰는지, 그리고 어떻게 구현하면 좋은지를 처음부터 차근차근 정리해본다.
싱글톤이란?
간단히 말해,
"클래스의 인스턴스를 애플리케이션 전체에서 하나만 존재하도록 보장하는 패턴"이다.
설정 정보, 로그 기록기, 캐시 등 공통으로 쓰이고 하나만 있어야 하는 객체들에 주로 쓰인다.
왜 싱글톤을 쓸까?
- 중복 인스턴스 방지
→ 동일한 객체를 여러 번 만들지 않아 메모리 낭비를 막을 수 있다. - 공유 상태 유지
→ 모든 코드에서 같은 객체를 참조하므로 설정값이나 상태가 일관된다. - 전역 접근
→ 어디서든 getInstance()를 통해 접근 가능하다.
싱글톤 구현 방법
자바에서 싱글톤을 구현하는 방법은 다양하다. 그중 대표적인 3가지 방법을 살펴보자.
1. Eager Initialization (즉시 초기화)
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
장점
- 클래스가 로딩될 때 인스턴스를 생성하므로 스레드에 안전하다.
단점
- 프로그램 시작 시 무조건 생성되기 때문에, 필요하지 않은 경우에도 메모리를 차지할 수 있다.
2. Lazy Initialization (지연 초기화 + 동기화)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
장점
- 인스턴스가 필요한 시점에 생성된다.
단점
- synchronized 키워드로 인해 매번 락을 획득해야 하므로 성능이 떨어질 수 있다.
3. Double-Checked Locking + volatile (권장 방식)
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
장점
- 인스턴스가 필요할 때만 생성되고,
- 첫 호출 이후에는 synchronized 블록을 타지 않아 성능 저하도 없다.
volatile 키워드를 쓰는 이유?
- 자바의 메모리 모델 상, 객체 생성 시 명령어 재정렬(Instruction Reordering) 이 일어날 수 있는데,
volatile을 쓰면 이를 방지할 수 있다.
더보기참고:
자바 객체생성은
1. 메모리 할당
2. 생성자 호출
3. 변수에 참조할당
순으로 이뤄지는데, 컴파일러나 CPU가 명령어 재정렬(Instruction Reordering) 을 하게 되면 다음처럼 바뀔 수 있다.
메모리 할당 → 변수에 참조 할당 → 생성자 호출
그럼 다른 스레드가 instance != null이 되는 걸 보고 미리 접근해버릴 수 있다! → 생성자도 안 끝났는데 객체 사용 - 또한 한 스레드의 변경 내용을 다른 스레드가 바로 인식할 수 있도록 가시성(visibility) 도 보장해준다.
정리
| 구현 방식 | 스레드 안전 | 성능 | 특징 |
| Eager | O | 좋음 | 항상 생성됨 |
| Lazy + synchronized | O | 나쁨 | 락 오버헤드 |
| Double-Checked + volatile | O | 좋음 | 가장 실무에 적합 |
싱글톤은 간단하지만, 멀티스레드 환경을 고려하지 않으면 의도치 않게 여러 인스턴스가 만들어질 수 있다.
특히 토큰 관리, 설정 공유, 전역 상태 관리 같은 기능을 구현할 땐 반드시 신중하게 설계해야 한다.
요즘은 Spring 프레임워크처럼 싱글톤을 자동으로 관리해주는 환경도 많지만,
기본 원리를 정확히 알고 있어야 내부에서 어떤 일이 일어나는지 이해할 수 있다.
반응형
'CS > Design Patterns' 카테고리의 다른 글
| 커맨드 패턴(Command Pattern) (0) | 2025.04.29 |
|---|