Post

[Java] 싱글턴 패턴(Singleton pattern)

싱글턴 패턴이란?


싱글턴(Single) 패턴은 프로그램 전체에서 오직 하나의 인스턴스만 존재하도록 보장하는 디자인 패턴이다. 주로 공통된 설정이나 자원, 전역적으로 접근해야 하는 객체에 사용된다.

  • 설정 관리 객체
  • 로그 기록 객체
  • DB 연결 객체

Spring 프레임워크에서는 싱글턴 패턴을 기본적으로 적용한다.
빈(Bean) 하나를 만들어서 앱 전역에 공유하는 방식

주요 특징


  • 인스턴스 하나만 생성됨
    클래스가 최초 한 번만 객체를 생성함
  • 전역 접근 가능
    어디서든 동일한 인스턴스에 접근 가능
  • 생성 제어
    외부에서 직접 new 하지 못하도록 생성자를 막음

예제1️⃣


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {
    private static Singleton instance;

    // ⭐ 생성자 private → 외부에서 new Singleton() 불가능
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();  // 처음 호출될 때 생성
        }
        // ⭐ 이미 생성된 인스턴스가 있다면 그것을 반환한다.
        return instance;
    }
}
  • 생성자가 private 인지 확인

멀티쓰레드 환경에서의 문제점


하지만 위 예제1️⃣ 방식은 멀티쓰레드 환경에서 동시에 여러 인스턴스가 생성될 때 문제가 생긴다. 이를 방지하기 위해 보통 동기화(Synchronized)를 사용하거나, 이른 초기화(Eager Initialization) 또는 Double-Checked Locking을 사용한다.

Double-Checked Locking

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {  // 1차 체크
            synchronized (Singleton.class) {
                if (instance == null) {  // 2차 체크
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

volatile 키워드

  • Java 변수를 Main Memory에 저장하겠다라는 것을 명시하는 것
  • 변수의 값을 Read할 때마다 CPU cache에 저장된 값이 아닌 Main Memory에서 읽는 것
  • 또한, 변수의 값을 Write할 때마다 Main Memory에 까지 작성하는 것

synchronized 키워드

  • synchronized로 지정된 임계영역은 한 스레드가 이 영역에 접근하여 사용할때 lock이 걸림으로써 다른 스레드가 접근할 수 없게 된다.
  • lock은 해당 객체당 하나씩 존재한다.
  • synchronized로 설정된 임계영역은 lock 권한을 얻은 하나의 객체만이 독점적으로 사용한다.

이른 초기화 방식 (Thread-safe)

1
2
3
4
5
6
7
8
9
public class Singleton {
    private static final Singleton instance = new Singleton(); // ✅

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

장단점 요약


장점단점
메모리 절약테스트하기 어려움 (전역 상태)
전역 인스턴스 공유의존성 주입이 어려움
접근이 간편멀티스레드 환경에서는 주의 필요

© Hoon. Some rights reserved.