CS

싱글톤 패턴(Singleton Pattern)

Twisted 2025. 2. 25. 00:43

싱글톤 패턴이란 무엇일까?

싱글톤 패턴(Singleton Pattern)은 객체의 인스턴스를 하나만생성하고, 이를 프로그램 전체에서 공유하도록 설계하는 디자인 패턴이다. 이는 글로벌 상태를 유지해야 하는 경우에 유용하며, 특히 설정,로그, 데이터베이스 연결관리, 스레드 풀 등에서 널리 사용된다.

 

싱글톤 패턴의 특징

  • 단일 인스턴스 : 클래스의 인스턴스가 하나만 생성되도록 보장.
  • 전역 접근 가능 : 프로그램 내 어디에서든 동일한 인스턴스를 호출할 수 있음.
  • 메모리 절약 : 불필요한 객체 생성을 방지하여 성능을 향상.
  • 멀티스레드 환경에서 동기화 문제 고려 필요 : 여러 스레드에서 동시에 접근할 경우 동기화 문제를 해결해야 한다.

 

싱글톤 패턴의 구현 방법

1) Eager Initialization (이른 초기화)

public class Singleton {
    private static final Singleton instance = new Singleton();
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        return instance;
    }
}
  • 설명 : 클래스가 로딩될 때 인스턴스를 미리 생성하는 방식.
  • 장점 : 구현이 간단하고 멀티스레드 환경에서도 안전함.
  • 단점 : 사용되지 않아도 인스턴스를 생성하기 때문에 메모리 낭비할 가능성이 있다.

2) Lazy Initialization (지연 초기화)

public class Singleton {
    private static Singleton instance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 설명 : 필요할 때 인스턴스를 생성하는 방식.
  • 장점 : 사용되지 않으면 인스턴스를 생성하지 않아 메모리 절약이 가능하다.
  • 단점 : 멀티스레드 환경에서 여러 개의 인스턴스가 생성될 위험이 있다.

3) Thread-Safe Singleton (동기화 방식)

public class Singleton {
    private static Singleton instance;
    
    private Singleton() {}
    
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 설명 : 필요할 때 인스턴스를 생성하는 방식.
  • 장점 : 사용되지 않으면 인스턴스를 생성하지 않아 메모리 절약 가능하다.
  • 단점 : 멀티스레드 환경에서 여러 개의 인스턴스가 생성될 위험이 있다.

4) Double-Checked Locking (이중 검사 락)

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;
    }
}
  • 설명 : synchronized 블록을 최소화하여 성능을 향상.
  • 장점 : 멀티스레드 환경에서 안전하면서도 동기화 비용을 최소화할 수 있다.
  • 단점 : volatitle 키워드를 지원하지 않는 일부 JVM에서는 동작하지 않을 수 있다.

5) Bill Pugh Singleton (정적 내부 클래스 활용)

public class Singleton {
    private Singleton() {}
    
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}
  • 설명 : 정적 내부 클래스를 활용하여 JVM의 클래스 로딩 매커니즘을 이용.
  • 장점 : Lazy Initialization을 지원하면서도 동기화 문제 해결 가능하다.
  • 단점 : 코드 구조가 상대적으로 복잡할 수 있다.

 

6) Bill Pugh Singleton (정적 내부 클래스 활용)

public enum Singleton {
    INSTANCE;
    
    public void doSomething() {
        System.out.println("싱글톤 인스턴스 메서드 호출");
    }
}
  • 설명 : Java의 enum을 이용하여 싱글톤을 구현
  • 장점 : 직렬화/역직렬화 문제를 자동으로 해결하며, 멀티스레드 환경에서도 안전하다.
  • 단점 : 클래스가 아니라 enum을 사용해야 한다는 제한이 있다.

 

싱글톤 패턴의 장단점

장점

  • 전역적으로 하나의 인스턴스를 공유하여 메모리 사용을 최적화할 수 있다.
  • 객체 생성 비용이 높은 경우 효과적이다.
  • 설정, 캐시, 로그 관리 등에서 유용하게 사용된다.

단점

  • 전역 상태를 관리하기 때문에 테스트가 어려워질 수 있다.
  • 멀티스레드 환경에서 잘못된 구현을 할 경우 동기화 문제가 발생할 수 있다.
  • 의존성이 높아져서 코드 유지보수가 어려울 수 있다.
  • 단일 책임 원칙에 위배할 수 있다.

 

 

어떤 경우에 싱글톤 패턴을 사용하면 좋을까?

  • 데이터베이스 연결 관리 : 여러 객체가 동일한 DB연결을 공유해야 할 때
  • 설정 정보 관리 : 애플리케이션 전체에서 동일한 설정을 유지해야 할 때
  • 로깅 시스템 : 프로그램 전반에서 동일한 로깅 인스턴스를 공유할 때
  • 캐시 시스템 : 동일한 데이터를 반복적으로 조회해야 할 때
  • 스레드 풀 관리 : 제한된 개수의 스레드를 효율적으로 관리할 때