JAVA/JAVA Design Pattern

Singleton Pattern in Java

임베디드 친구 2024. 12. 19. 13:04
반응형

1. Singleton Pattern의 개념

싱글톤 패턴(Singleton Pattern)은 클래스의 인스턴스가 하나만 생성되도록 보장하는 디자인 패턴입니다. 주로 공유된 리소스에 접근하거나, 전역 상태를 관리할 때 사용됩니다.

Singleton 패턴의 특징:

  • 클래스가 하나의 인스턴스만 가지도록 제한
  • 전역 접근점(Global Access Point)을 제공
  • 메모리 낭비 방지 및 시스템 자원 절약

2. Singleton Pattern의 구현 방법

싱글톤 패턴은 다양한 방법으로 구현될 수 있으며, 구현 시 쓰레드 안전성(Thread Safety)을 고려해야 합니다.

이른 초기화(Eager Initialization)

클래스가 로드될 때 싱글톤 인스턴스를 생성하는 방식입니다.

public class Singleton {
    // 이른 초기화: 인스턴스를 바로 생성
    private static final Singleton instance = new Singleton();

    // 생성자를 private로 설정해 외부에서 인스턴스 생성 방지
    private Singleton() { }

    // 인스턴스 반환 메서드
    public static Singleton getInstance() {
        return instance;
    }
}

장점: 구현이 간단하고 쓰레드 안전성을 보장합니다.

단점: 클래스 로딩 시 인스턴스를 생성하기 때문에 리소스 낭비가 발생할 수 있습니다.

지연 초기화(Lazy Initialization)

인스턴스를 필요할 때 생성하는 방식입니다.

public class Singleton {
    private static Singleton instance;

    private Singleton() { }

    // 인스턴스가 없으면 생성
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

장점: 인스턴스가 필요할 때만 생성되어 메모리 낭비를 방지합니다.

단점: 멀티 쓰레드 환경에서 쓰레드 안전성을 보장하지 못합니다.

쓰레드 안전한 지연 초기화(Thread-Safe Lazy Initialization)

synchronized 키워드를 사용해 멀티 쓰레드 환경에서도 안전하게 동작하도록 합니다.

public class Singleton {
    private static Singleton instance;

    private Singleton() { }

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

장점: 쓰레드 안전성을 보장합니다.

단점: synchronized는 성능 저하를 유발할 수 있습니다.

더블 체크 락킹(Double-Checked Locking)

성능을 개선하기 위해 synchronized 블록을 최소화하는 방식입니다.

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() { }

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

장점: 쓰레드 안전성을 유지하면서도 성능 저하를 최소화합니다.

단점: 코드가 다소 복잡합니다.

Bill Pugh Singleton

내부 정적 클래스를 사용해 Lazy Initialization쓰레드 안전성을 동시에 만족하는 방법입니다.

public class Singleton {
    private Singleton() { }

    private static class SingletonHelper {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHelper.INSTANCE;
    }
}

장점: 가장 효율적이고 간단하며 쓰레드 안전성을 보장합니다.


3. Singleton Pattern의 클래스 다이어그램

+----------------+
|   Singleton    |
+----------------+
| - instance     |
|----------------+
| + getInstance()|
+----------------+

4. Singleton Pattern의 실제 사용 사례

로그 관리

애플리케이션 전반에서 로그를 관리할 때 Singleton을 사용하면 여러 클래스가 하나의 로그 인스턴스에 접근할 수 있습니다.

public class Logger {
    private static Logger instance;

    private Logger() { }

    public static Logger getInstance() {
        if (instance == null) {
            instance = new Logger();
        }
        return instance;
    }

    public void log(String message) {
        System.out.println("[LOG]: " + message);
    }
}

// 사용 예시
public class Main {
    public static void main(String[] args) {
        Logger logger = Logger.getInstance();
        logger.log("Singleton 패턴 예제");
    }
}

설정 파일 관리

애플리케이션의 설정 값을 Singleton으로 관리하면 여러 클래스에서 공유된 설정 정보에 접근할 수 있습니다.


5. 결론

싱글톤 패턴은 클래스의 인스턴스를 하나로 제한하여 자원 관리전역 접근성을 보장하는 강력한 디자인 패턴입니다. 다양한 구현 방법과 쓰레드 안전성을 이해하고 상황에 맞게 적용하면 효율적이고 안전한 소프트웨어를 개발할 수 있습니다.


요약

구현 방법 쓰레드 안전성 장점 단점
이른 초기화 O 구현이 간단, 쓰레드 안전 리소스 낭비 가능
지연 초기화 X 메모리 절약 멀티 쓰레드 안전하지 않음
Thread-Safe Lazy Init O 쓰레드 안전 성능 저하
더블 체크 락킹 O 성능과 안전성 모두 만족 코드가 복잡
Bill Pugh Singleton O 효율적, 쓰레드 안전 구현이 다소 생소할 수 있음
반응형