호비시의 끄적끄적

Singleton Pattern 본문

Back/Spring

Singleton Pattern

호비시 2022. 7. 17. 16:48

Singleton Pattern

싱글톤 패턴이란 디자인 패턴중 하나로, 애플리케이션이 시작될 때 객채의 인스턴스가 오직 1개만 생성되는 패턴을 말한다.

사용하는 이유

  1. 메모리 낭비 방지
    하나의 인스턴스만 고정 메모리 영역에 생성하기 때문에 해당 객체에 접근할 때 메모리 낭비를 방지할 수 있다.
  2. 속도 빠름
    이미 생성된 인스턴스를 활용하기에 속도 측면에서 이점이 있다.
  3. 데이터 공유하기 유리
    전역으로 사용하는 인스턴스이기 때문에 다른 여러 클래스에서 데이터를 공유하기 쉽다.

주의할 점

싱글톤 인스턴스가 너무 많은 일을 하거나 많은 데이터를 공유할 경우 다른 클래스의 인스턴스들 간에 결합도가 높아진다.
따라서 수정이 어려워지고, 테스트하기가 어렵다.

또한 멀티스레드 환경에서 문제점이 많다. 여러개의 인스턴스가 생성될 수가 있다. 또한 변수값의 일관성이 없어질 수 있다.

해결책

1. Lazy Initialization

public class ThreadSafeLazyInitialization{
    private static ThreadSafeLazyInitialization instance;
    private ThreadSafeLazyInitialization(){}
    public static synchronized ThreadSafeLazyInitialization getInstance(){
        if(instance == null){
            instance = new ThreadSafeLazyInitialization();
        }
    return instance;
    }
}

private static으로 정적변수에 인스턴스를 만들어서 초기화 시키는 방법
synchronized 동기화를 활용해 스레드를 안전하게 만드는 방법 -> but 성능저하가 발생함

 

2. Thread Safe Lazy Initialization + Double-checked Locking

public class ThreadSafeLazyInitialization {
	private volatile static ThreadSafeLazyInitialization instance;
    private ThreadSafeLazyInitialization(){}
    public static ThreadSafeLazyInitialization getInstance(){
    	if(instance == null){
        	synchronized (ThreadSafeLazyInitialization.class) {
            	if(instance == null)
                	instance = new ThreadSafeLazyInitialization();
                }
            }
        return instance;
    }
}


1번 방법의 성능저하를 완화시키는 방법 -> but완벽한 방법은 아님

첫번째 if 문에서 인스턴스의 존재 여부를 체크하고, 두번째 if 문에서 다시 한번 체크할 때 동기화 시켜서 인스턴스를 생성

 

3. Initialization on demand holder idiom

public class Something {
	private Something() {    }     
    private static class LazyHolder {        
    	public static final Something INSTANCE = new Something();    
    }
    public static Something getInstance() {
    	return LazyHolder.INSTANCE;
    }
}

클래스 안에 Holder를 두어 JVM의 Class Loader가 클래스를 load하는 시점을 이용한 방법JVM의 클래스 초기화 과정에서 보장되는 원자적 특성을 이용하여 싱글턴의 초기화 문제에 대한 책임을 JVM에 떠넘긴다. 

holder 안에 선언된 instance가 static 이기 때문에 클래스 로딩시점에 한번만 호출되며, final을 사용해 다시 값이 할당되지 않도록 만든 방법

가장 많이 사용되고 일반적인 Singleton 클래스 사용 방법

'Back > Spring' 카테고리의 다른 글

Java Static, Final  (0) 2022.07.14
Spring Security  (0) 2022.07.10
Stream  (0) 2022.07.03
Lombok ?  (0) 2022.06.28
POJO 란?  (0) 2022.06.23
Comments