싱글턴 패턴(Singleton Pattern)은 클래스의 인스턴스를 하나만 생성하도록 제한하는 디자인 패턴이다. 특정 객체가 애플리케이션에서 하나만 존재해야 할 때 유용하다.
메모리 절약
인스턴스를 하나만 생성하므로 메모리를 절약할 수 있습니다.
데이터 일관성 유지
하나의 인스턴스를 공유하므로 상태가 일관되게 유지됩니다.
접근 제어 및 동기화
인스턴스 생성과 접근을 제어하여 스레드 안전성을 보장할 수 있습니다.
글로벌 상태 관리
설정값, 로그, 설정 등을 전역에서 하나의 객체로 관리할 수 있습니다.
싱글턴 패턴을 적용하지 않으면 같은 객체를 여러 번 생성하게 됩니다. 이 경우 메모리 낭비와 상태 불일치가 발생할 수 있습니다.
public class Logger {
public void log(String message) {
System.out.println("Log: " + message);
}
}
public class Main {
public static void main(String[] args) {
Logger logger1 = new Logger();
Logger logger2 = new Logger();
logger1.log("First log message");
logger2.log("Second log message");
System.out.println(logger1 == logger2); // false (서로 다른 객체)
}
}
logger1과 logger2는 서로 다른 인스턴스이므로 상태가 일관되지 않습니다.싱글턴 패턴에서는 인스턴스를 하나만 생성하고, 이를 전역에서 공유합니다.
public class Logger {
// 유일한 인스턴스를 저장할 정적 변수
private static Logger instance;
// 생성자를 private으로 선언해 외부에서 인스턴스화 방지
private Logger() {}
// 유일한 인스턴스를 반환하는 메서드
public static Logger getInstance() {
if (instance == null) {
instance = new Logger();
}
return instance;
}
public void log(String message) {
System.out.println("Log: " + message);
}
}
public class Main {
public static void main(String[] args) {
Logger logger1 = Logger.getInstance();
Logger logger2 = Logger.getInstance();
logger1.log("First log message");
logger2.log("Second log message");
System.out.println(logger1 == logger2); // true (같은 객체)
}
}
Logger.getInstance() 호출 시 인스턴스가 없는 경우에만 생성 멀티스레드 환경에서 안전하게 작동하도록 synchronized 키워드를 추가하면 됩니다.
public class Logger {
private static Logger instance;
private Logger() {}
public static synchronized Logger getInstance() {
if (instance == null) {
instance = new Logger();
}
return instance;
}
public void log(String message) {
System.out.println("Log: " + message);
}
}
synchronized를 사용하면 멀티스레드 환경에서 경쟁 상태(race condition)를 방지할 수 있습니다. 하지만 성능이 저하될 수 있습니다.
| 항목 | 싱글턴 적용 전 | 싱글턴 적용 후 |
|---|---|---|
| 인스턴스 수 | 여러 개 | 하나만 유지 |
| 상태 일관성 | 불일치 가능 | 일관성 유지 |
| 메모리 사용 | 인스턴스마다 메모리 사용 | 하나의 인스턴스만 메모리 사용 |
| 스레드 안전성 | 경쟁 상태 발생 가능 | synchronized 또는 double-checked locking 적용 가능 |
synchronized 또는 Double-Checked Locking 적용