디자인패턴) 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();
	}
}

댓글

가장 많이 본 글