디자인패턴) Singleton 싱글톤 패턴 몇가지 방법들
Singleton
일반적으로 하 나의 인스턴스만을 생성하기 위해 사용되는 패턴입니다.
Eager Initialization
- 클래스 필드에 static으로 선언 및 생성 합니다.
- 클래스 로더에의해 클래스가 최초 로딩 될 때 생성되므로 thread-safe합니다.
- 항상 객체가 생성되어있는 상태이므로 사용하지 않아도 메모리를 차지하고있어 비효율적입니다.
public class EagerInitialization { private static EagerInitialization instance = new EagerInitialization(); private EagerInitialization() {} public static EagerInitialization getInstance() { return instance; } }
Lazy Initialization
- 객체가 사용될 시점에 객체를 생성하게 됩니다.
- 필요할 시에 객체가 생성되기 때문에 메모리 낭비가 덜 합니다.
- multi-thread환경에서 동시에 여러번 호출될 경우 둘 이상 생성 할 가능성이 있습니다.
public class LazyInitialization { private static LazyInitialization instance; private LazyInitialization() {} public static LazyInitialization getInstance() { if(instance == null) { instance = new LazyInitialization(); } return instance; } }
ThreadSafe Lazy Initialization
- Lazy Initialization방식에 synchronized를 사용하여 멀티스레드 환경의 문제점을 보완(임계구역을 설정)
- 여러 스레드에서 동시 접근해도 객체가 여러 개 생성될 염려 없습니다.
- sychronized 기능으로 인해 자바 내부적으로 많은 처리가 발생, getInstance() 함수가 많이 호출 된다면 성능 저하가 발생 합니다.
public class TSLazyinitialization { private static TSLazyinitialization instance; private TSLazyinitialization() {} public static synchronized TSLazyinitialization getInstance() { if(instance == null) instance = new TSLazyinitialization(); return instance; } }
Initialization on demand holder idiom
- LazyHolder 라고도 합니다. sychronized 없어도 멀티 스레드 환경에서 안정하고 성능도 가장 나은 방법으로 알려져있어 많이 사용되는 방법이라고 합니다.
- LazyHolder클래스는 HolderInitialization의 getInstance를 호출하는 순간 클래스 로딩 및 초기화가 이루어 집니다. 이 시점에는 thread-safe를 보장 받을 수 있습니다.
public class HolderInitialization { private HolderInitialization() {} public static HolderInitialization getInstance() { return LazyHolder.instance; } private static class LazyHolder{ private static final HolderInitialization instance = new HolderInitialization(); } }
댓글
댓글 쓰기