싱글턴(Singleton) 패턴은 오직 하나의 인스턴스만 생성되도록 보장하고, 해당 인스턴스를 어디서든 접근할 수 있도록 하는 디자인 패턴입니다. 주로 시스템에서 전역적으로 관리해야 할 객체를 만들 때 사용됩니다.
싱글턴 패턴의 특징
- 단 하나의 인스턴스
특정 클래스의 인스턴스가 애플리케이션에서 하나만 생성되도록 보장합니다. - 글로벌 접근
생성된 인스턴스는 어디서든 동일한 객체를 참조할 수 있습니다. - 생성 제어
외부에서 클래스의 인스턴스를 직접 생성하지 못하도록 생성자를 제한합니다.
싱글턴(Singleton) 패턴은 오직 하나의 인스턴스만 생성되도록 보장하고, 해당 인스턴스를 어디서든 접근할 수 있도록 하는 디자인 패턴입니다. 주로 시스템에서 전역적으로 관리해야 할 객체를 만들 때 사용됩니다.
싱글턴 패턴의 특징
- 단 하나의 인스턴스
특정 클래스의 인스턴스가 애플리케이션에서 하나만 생성되도록 보장합니다. - 글로벌 접근
생성된 인스턴스는 어디서든 동일한 객체를 참조할 수 있습니다. - 생성 제어
외부에서 클래스의 인스턴스를 직접 생성하지 못하도록 생성자를 제한합니다.
싱글턴 패턴의 구현
1. 기본 싱글턴
- 클래스의 인스턴스를 정적으로 생성하고, getInstance() 메서드로 반환합니다.
public class Singleton {
private static Singleton instance; // 정적 변수로 인스턴스 보관
private Singleton() {
// private 생성자: 외부에서 new를 통해 인스턴스 생성 금지
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // 최초 호출 시 인스턴스 생성
}
return instance;
}
}
// 사용
Singleton singleton = Singleton.getInstance();
문제점:
- 멀티스레드 환경에서 동시 호출 시 인스턴스가 두 번 생성될 수 있습니다.
2. 스레드 안전 싱글턴
- 동기화(synchronization)를 통해 멀티스레드 환경에서도 안전하게 동작하도록 개선합니다.
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
단점:
- getInstance() 메서드가 호출될 때마다 동기화 비용이 발생하여 성능 저하 가능.
3. 더블 체크 락(Double-Checked Locking)
- 동기화 범위를 줄여 성능 문제를 해결한 방식입니다.
public class Singleton {
private static volatile Singleton instance; // volatile로 가시성 보장
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 첫 번째 체크
synchronized (Singleton.class) {
if (instance == null) { // 두 번째 체크
instance = new Singleton();
}
}
}
return instance;
}
}
장점:
- 성능과 스레드 안전성 모두 보장.
4. 이른 초기화(Eager Initialization)
- 클래스 로딩 시점에 인스턴스를 생성합니다.
멀티스레드 환경에서도 안전하며 구현이 간단하지만, 필요하지 않은 경우에도 메모리를 차지할 수 있습니다.
public class Singleton {
private static final Singleton instance = new Singleton(); // 클래스 로딩 시 생성
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
5. 정적 내부 클래스(Static Inner Class)
- 정적 내부 클래스의 특성을 활용한 방법으로, **지연 초기화(lazy initialization)**와 스레드 안전성을 동시에 보장합니다.
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton(); // 초기화
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
장점:
- 클래스가 로드될 때는 인스턴스가 생성되지 않고, getInstance() 호출 시에만 초기화됩니다.
6. Enum을 이용한 싱글턴
- Java enum은 인스턴스가 단 하나만 생성되도록 보장하므로, 싱글턴을 구현하기에 가장 간단하고 안전한 방법입니다.
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("Singleton using Enum");
}
}
// 사용
Singleton.INSTANCE.doSomething();
장점:
- 스레드 안전성이 보장되며, 리플렉션과 직렬화에 안전합니다.
싱글턴 패턴의 장점
- 전역 접근성: 애플리케이션의 여러 부분에서 같은 객체를 사용할 수 있음.
- 자원 절약: 하나의 인스턴스를 공유하므로 메모리와 리소스를 절약함.
- 제어 용이성: 객체 생성과 초기화를 한 곳에서 관리 가능.
싱글턴 패턴의 단점
- 테스트 어려움: 전역 상태를 유지하므로 테스트 시 의존성을 관리하기 어렵습니다.
- 유연성 부족: 다수의 인스턴스가 필요한 경우 확장성이 떨어짐.
- 결합도 증가: 전역적으로 접근할 수 있는 객체를 사용할 경우 코드 간 결합도가 증가할 수 있음.
사용 사례
- 데이터베이스 연결 객체
- 설정 클래스 (Configuration)
- 로깅 시스템 (Logger)
- 캐시 관리 (Cache Manager)
싱글턴은 유용하지만, 남용하면 결합도가 높아지고 코드 유지보수가 어려워질 수 있으므로 적절히 사용해야 합니다.
'JAVA' 카테고리의 다른 글
로그인 처리 (2) | 2024.09.02 |
---|---|
JPA -I need Method (0) | 2024.08.30 |
클라이언트와 서버 (0) | 2024.08.26 |
Jpa 동작 기본 정리하기 (0) | 2024.08.23 |
복제 생성자 (0) | 2024.08.19 |