[Design Pattern] 싱글턴 패턴(Singleton Pattern)

2024. 9. 27. 13:23·Computer Science/Design Pattern

"헤드 퍼스트 디자인 패턴(개정판)"을 읽고 정리한 내용입니다.

5. 하나뿐인 특별한 객체 만들기

싱글턴 패턴

 싱글턴 패턴(Singleton Pattern)은 클래스 인스턴스가 오직 1개만 있음을 보장하고, 그 인스턴스로의 전역 접근을 제공한다.

 

멀티스레딩 문제 해결하기

public class Singleton {
    private static Singleton uniqueInstance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        
        return uniqueInstance;
    }
}

 위 코드의 경우에는 스레드가 여러개 접근할 경우에 동기화 문제가 발생할 수 있다.

 

멀티스레딩 해결 방법 1 : 지연 초기화(Lazy Initialization)

public class Singleton {
    private static Singleton uniqueInstance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }

        return uniqueInstance;
    }
}

 멀티스레드 환경에서는 위 코드와 같이 synchronized 키워드를 사용해서 한 스레드가 메소드 사용을 끝내기 전까지 블로킹하도록 수정한다. 하지만, 이 방식처럼 메소드 를 동기화하면 성능이 100배 정도 저하된다.

 

멀티스레딩 해결 방법 2 : 즉시 초기화(Eager Initialization)

public class Singleton {
    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        return uniqueInstance;
    }
}

 위 코드처럼 정적 초기화 부분에서 인스턴스를 생성할 경우에는 멀티스레드 환경에서도 문제가 발생하지 않고 편하게 사용할 수 있다. 하지만, 애플리케이션이 시작될 때 인스턴스를 바로 생성하기 때문에 인스턴스가 사용되지 않더라도 메모리를 차지하게 된다.

 

멀티스레딩 해결 방법 3 : 이중 검사 잠금(DCL, Double-Checked Locking)

public class Singleton {
    private volatile static Singleton uniqueInstance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (uniqueInstance == null) { // 첫 번째 Check
            synchronized (Singleton.class) { // 동기화 블록
                if (uniqueInstance == null) { // 두 번째 Check
                    uniqueInstance = new Singleton();
                }
            }
        }

        return uniqueInstance;
    }
}

 이 방식은 인스턴스가 이미 생성된 경우에 불필요한 동기화를 피하기 위해서 인스턴스가 null 인지 두 번 검사하는 방법이다. 첫 번째 Check 부분에서는 동기화 없이 빠르게 검사하고, 두 번째 Check는 동기화 블록 안에서 검사해서 인스턴스가 아직 생성되지 않은 경우에 객체를 생성한다. 위 코드는 동기화 비용을 최소화하면서도 멀티스레드 환경에서 안전하다.

 

멀티스레딩 해결 방법 4 : ENUM

enum Singleton {
    UNIQUE_INSTANCE;
}

public class SingletonTest {
    public static void main(String[] args) {
        Singleton singleton = Singleton.UNIQUE_INSTANCE;
        
    }
}

 가장 안전하고 간단하게 사용할 수 있는 Singleton 패턴의 구현이다. 자바의 enum은 동기화 문제, 클래스 로딩 문제, 리플렉션, 직렬화와 역직렬화 문제에 대해서 안전을 보장한다.

저작자표시 비영리 변경금지 (새창열림)
'Computer Science/Design Pattern' 카테고리의 다른 글
  • [Design Pattern] 어탭터 패턴(Adapter Pattern), 퍼사드 패턴(Facade Pattern)
  • [Design Pattern] 커맨드 패턴(Command Pattern)
  • [Design Pattern] 팩토리 패턴(Factory Pattern)
  • [Design Pattern] 데코레이터 패턴(Decorator Pattern)
SiwonHae
SiwonHae
프로그래밍을 공부하고 있는 학생입니다.
  • SiwonHae
    시원해의 블로그
    SiwonHae
  • 전체
    오늘
    어제
    • 전체보기 (149)
      • PS(Problem Solving) (94)
        • C (25)
        • C++ (33)
        • JAVA (36)
      • Algorithm & Data Structure (13)
      • Computer Science (12)
        • Network (2)
        • Design Pattern (10)
      • Back-end (6)
        • Spring (5)
      • Front-end (1)
        • React (1)
      • JAVA (4)
      • 정보처리기사 (17)
      • SQLD (2)
  • 블로그 메뉴

    • 홈
    • 방명록
    • 글쓰기
  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.0
SiwonHae
[Design Pattern] 싱글턴 패턴(Singleton Pattern)
상단으로

티스토리툴바