✅ 1. 싱글톤 패턴이란?
- 소프트웨어 디자인 패턴 중 하나로, 프로그램 전체에서 단 하나의 인스턴스만 생성되도록 보장하는 패턴
- 어떤 클래스의 인스턴스가 오직 하나만 생성되도록 제한하고, 그 인스턴스에 접근할 수 있는 전역적인 접근 메서드를 제공하는 패턴
🎯 왜 쓰는가?
- 공통된 자원을 모든 곳에서 동일하게 사용해야 할 때
- 인스턴스를 공유해야 할 때 (예: DB 연결, 설정 객체, 로그 시스템 등)
- 메모리 낭비를 막고, 일관된 동작 보장을 위해
🔁 예시 상황
Logger
: 로그 관리자는 하나만 있어야 일관된 로그 기록 가능
DatabaseManager
: DB 커넥션 객체를 하나만 만들어 재사용
환경 설정 클래스
: 설정 정보를 읽고 캐시
✅ 2. 구조 요약 (Java 기준)
public class Singleton {
private static Singleton instance; // [1] 유일한 인스턴스를 저장할 변수
private Singleton() {} // [2] 생성자를 private으로 막음
public static Singleton getInstance() { // [3] 인스턴스를 반환하는 정적 메서드
if (instance == null) {
instance = new Singleton(); // 처음 한 번만 생성됨
}
return instance;
}
}
✅ 3. 핵심 포인트
요소 | 설명 |
private 생성자 | 외부에서 new Singleton() 으로 생성 못 하게 막음 |
static 인스턴스 변수 | 클래스에 하나만 존재하는 공유 인스턴스 |
getInstance() | 인스턴스를 반환하는 정적 메서드 |
⚠️ 멀티스레드 환경에서는?
단일 인스턴스 생성 중 동시 접근 문제 발생 가능
🛡 해결 방법: synchronized 키워드
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
혹은 Double-Checked Locking +
volatile
사용✅ 4. 싱글톤의 장단점
✅ 장점
- 인스턴스가 하나만 존재 → 메모리 절약
- 전역 접근 가능 → 공통 상태 유지 쉬움
- 클래스간 의존성 낮춤
❌ 단점
- 테스트 어려움 (인스턴스 상태 공유)
- 전역 상태 → 예상치 못한 사이드이펙트
- 멀티스레드 환경에서 동기화 필요
🧠 싱글톤 사용 시기
- 전역 설정 클래스
- 로그 기록기
- 공통 유틸리티
- DB 커넥션 풀
- 쓰레드 풀
📌 정리 문장
싱글톤 패턴은 프로그램에서 인스턴스를 오직 하나만 생성하고, 그 인스턴스에 어디서든 접근 가능하게 해주는 디자인 패턴
실습

Doorman
package ex04;
public class Doorman {
// instance는 static 공간에 저장되고, Doorman의 Heap의 주소를 가진다
public static Doorman instance = new Doorman(); // 상태확인
private Doorman() {
}
// 객체의 책임
public void 쫓아내(Animal animal) {
System.out.println(animal.getName() + " 나가!!");
}
}
- main 시작 전에 한 번만 띄워서 유지
App
package ex04;
public class App {
public static void main(String[] args) {
Mouse m1 = new Mouse();
Cat c1 = new Cat();
Doorman d1 = Doorman.instance;
d1.쫓아내(m1);
d1.쫓아내(c1);
}
}
- 상태확인과 책임을 가진 메서드 구분
package ex04;
public class Doorman {
// 상태확인
public static Doorman instance = new Doorman();
// 책임을 가진 메서드 - 객체를 생성하는 책임
public static Doorman createInstance() {
return new Doorman();
}
private Doorman() {
}
// 객체의 책임
public void 쫓아내(Animal animal) {
System.out.println(animal.getName() + " 나가!!");
}
}
Share article