싱글톤(Singleton) 패턴은 애플리케이션에서 하나의 클래스에 대해 단 하나의 인스턴스만 생성되도록 보장하는 디자인 패턴입니다.
즉, 하나의 객체를 여러 곳에서 공유하여 사용할 때 유용합니다.
✅ 하나의 인스턴스를 전역적으로 공유 가능
✅ 메모리 낭비 방지 & 성능 최적화
✅ 객체의 일관된 상태 유지 가능
✅ 클래스의 인스턴스가 하나만 존재 (유일한 객체)
✅ 클라이언트가 동일한 인스턴스를 공유하여 사용 가능
✅ 글로벌 액세스(Global Access) 가능
✅ 객체 생성을 제한하여 메모리 절약 & 성능 최적화
📌 싱글톤 객체는 "하나의 객체를 여러 곳에서 동일한 상태로 공유"해야 할 때 사용됨.
public class Singleton {
private static final Singleton INSTANCE = new Singleton(); // 미리 생성
private Singleton() {} // private 생성자
public static Singleton getInstance() {
return INSTANCE;
}
}
📌 설명
✅ private static final Singleton INSTANCE
→ 클래스 로드 시점에 미리 객체 생성
✅ private Singleton()
→ 외부에서 객체 생성 방지
✅ getInstance()
→ 이미 생성된 인스턴스를 반환
✅ 단점: 객체가 사용되지 않아도 미리 생성됨 (불필요한 메모리 사용 가능)
public class Singleton {
private static Singleton instance; // 인스턴스 미리 생성 X
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // 최초 호출 시 생성
}
return instance;
}
}
📌 설명
✅ 필요할 때만 인스턴스를 생성 (지연 초기화, Lazy Initialization)
✅ 단점: 멀티스레드 환경에서 instance
가 중복 생성될 수 있음
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
📌 설명
✅ synchronized
키워드를 추가하여 멀티스레드 환경에서도 안전하게 사용 가능
✅ 단점: synchronized
로 인해 성능 저하 가능
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 1차 체크
synchronized (Singleton.class) {
if (instance == null) { // 2차 체크
instance = new Singleton();
}
}
}
return instance;
}
}
📌 설명
✅ volatile
키워드 사용 → 인스턴스 변경 시 즉시 반영
✅ synchronized
블록 안에서 2차 체크 → 성능 최적화
✅ 멀티스레드 환경에서도 안정적이며 성능도 고려한 방법 (가장 권장됨)
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("싱글톤 객체 실행");
}
}
📌 설명
✅ Enum
자체가 싱글톤을 보장 (JVM에서 자동 처리)
✅ 직렬화(Serialization), 리플렉션(Reflection) 공격에도 안전
✅ 멀티스레드 환경에서도 동기화 문제 없음
✅ 가장 안전한 방법! (Spring @Service
, @Component
와 유사한 동작)
✔ 객체 생성 비용 절감 → 인스턴스를 하나만 생성하므로 메모리 절약
✔ 전역 인스턴스 관리 가능 → 상태 유지 및 공유 가능
✔ 멀티스레드 환경에서 안전하게 사용 가능 (적절한 구현 시)
❌ 싱글톤 객체가 너무 많은 역할을 수행하면 결합도가 높아짐 (유지보수 어려움)
❌ 멀티스레드 환경에서 동기화 문제 발생 가능 (synchronized
적용 필요)
❌ 클래스의 의존성이 높아질 수 있음 → 객체 간 강한 결합 발생 가능
📌 싱글톤을 사용할 때는 객체의 책임을 분리하고, 필요할 때만 적용하는 것이 중요!
✅ Spring Framework의 @Service
, @Repository
, @Component
✅ Database Connection Pool (DB 커넥션 공유)
✅ Logging System (로그 관리)
✅ Configuration Manager (설정 파일 관리)
✅ Thread Pool 관리
📌 Spring에서는 기본적으로 @Service
, @Component
등의 빈(Bean)은 싱글톤으로 관리됨
비교 항목 | 싱글톤 객체 | 일반 객체 |
---|---|---|
인스턴스 개수 | 단 하나의 인스턴스만 존재 | 여러 개 생성 가능 |
메모리 사용량 | 적음 (하나만 유지) | 많음 (객체마다 메모리 할당) |
생성 비용 | 낮음 (한 번만 생성) | 높음 (매번 새 객체 생성) |
상태 유지 | 가능 (전역적으로 공유) | 개별 객체마다 다름 |
멀티스레드 문제 | 동기화 필요 | 개별 객체라 동기화 불필요 |
📌 객체를 공유해야 하는 경우 → 싱글톤 사용
📌 객체를 독립적으로 사용해야 하는 경우 → 일반 객체 사용
✅ 싱글톤(Singleton)은 객체를 단 하나만 생성하여 공유하는 패턴
✅ 메모리 절약 & 성능 최적화 가능하지만, 잘못 사용하면 결합도가 높아질 수 있음
✅ 멀티스레드 환경에서는 Double-Checked Locking
또는 Enum Singleton
방식이 가장 안전함
✅ Spring에서는 @Component
, @Service
, @Repository
등을 통해 기본적으로 싱글톤이 적용됨