1. 즉시 초기화
public class IdGnerator {
private AtomicLong id = new AtomicLong(0);
private static final IdGenerator instance = new IdGenerator();
private IdGenerator() {}
public static IdGenerator getInstance() {
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}
2. 늦은 초기화
public class IdGnerator {
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator() {}
public static synchronized IdGenerator getInstance() {
if(instance == null) {
instance = new IdGenerator();
}
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}
- 시간이 오래 걸리는 초기화 작업이 인스턴스가 사용되기 직전에 이루어지면 성능상 문제 발생 가능
- synchronized 키워드를 사용하는데, IdGenerator 클래스의 사용 빈도가 높다면 자주 잠금이 일어나고 이로 인해 병목 현상이 발생할 수 있음
3. 이중 잠금
- 늦은 초기화 방식 + 낮은 동시성을 해결
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator() {}
public static IdGenerator getInstance() {
if(instance == null) {
synchronized(IdGenerator.class) {
if(instance == null) {
instance = new IdGenerator();
}
}
}
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}
- CPU 명령이 재정렬되면
IdGenerator 클래스의 객체가 new 예약어를 통해 instance 멤버 변수가 지정딘 후,
초기화가 이루어지기 전에 다른 스레드에서 이 객체를 사용하려고 할 수 있음
- volatile 키워드를 인스턴스 멤버 변수에 추가하여 명령어 재정렬 방지
4. 홀더에 의한 초기화
- 지연 로딩 + 스레드 안정성
- 정적 내부 클래스 활용
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private IdGenerator() {}
private static class SingletonHolder {
private static final IdGenerator instance = new IdGenerator();
}
public static IdGenerator getInstance() {
return SingletonHolder.instance;
}
public long getId() {
return id.incrementAndGet();
}
}
IdGenerator 적재 시점에는 SingetonHolder는 적재되지 않지만,
getInstance()가 처음으로 호출될때 적재되고 생성된다
따라서 JVM에 의해 인스턴스의 유일성과 생성 프로세스의 스레드 안정성이 보장된다
5. 열거
- enum 활용하여 인스턴스 생성시 스레드 안정성과 유일성을 보장함
public enum IdGenerator {
INSTANCE;
private AtomicLong id = new AtomicLong(0);
public long getId() {
return id.incrementAndGet();
}
}
싱글톤 패턴은
클래스 간의 의존성을 감춘다
코드의 확장성/테스트에 영향을 미친다
매개변수가 있는 생성자를 지원하지 않는다
대안 ? 팩터리 패턴, DI 컨테이
[디자인패턴] 팩터리패턴 (0) | 2024.05.05 |
---|---|
[디자인패턴의 아름다움] 3장. 설계 원칙 : 단일책임원칙, 개방폐쇄 원칙 (0) | 2024.04.20 |
댓글 영역