Techbrad

[Design Pattern] Singleton 패턴 본문

Programming/Java

[Design Pattern] Singleton 패턴

brad.min 2023. 12. 15. 10:45
반응형

 

싱글톤 (Singleton) 패턴이란?

생성자를 통해 클래스가 여러번 호출이 되어도 하나의 인스턴스를 계속 재활용 하는 방식이다.

 

싱글톤 사용 이유와 언제 사용하는가?

프로그램 전반에서 하나의 인스턴스로만 사용하는 경우에 사용한다. 예를 들어 DB 커낵션 풀이나 로그 설정 등이 있을 수 있다.

 

싱글톤 패턴

싱글톤은 여러가지 방법으로 접근할 수 있다. 모든 접근 방법은 다음과 같은 공통 사항을 따른다

- 다른 클래스에서 생성자를 직접 호출하지 못하도록 private constructor를 사용한다.

- private static 의 변수를 사용하여 생성된 인스턴스를 전역에서 사용하도록 한다.

- public static을 사용해서 제어된 방식으로 인스턴스를 얻을 수 있도록 한다.

 

 

1. Eager initialization

Eager 단어 의미 그대로 열렬한 방법이다. getInstance 메소드 호출로 인스턴스를 생성하는 것이 아니라 클래스가 로드되는 시점에 인스턴스가 생성된다. 마치 너무 열정적이여서 준비를 미리미리 해놓는 느낌이다. 사용하지 않는데 메모리를 선점하기 때문에 성능에 좋지 않다. 또한 exception을 관리할 수 있는 옵션을 제공하지 않는다.

 

public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

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

 

 

2. Static block initializtion

Eager 방법과 비슷하지만 예외를 처리하는 방법이다.

 

public class StaticBlockSingleton {
    private static StaticBlockSingleton instance;
    
    private StaticBlockSingleton() {}

    static {
        try{
            instance = new StaticBlockSingleton();
        } catch (Exception e){
            throw new RuntimeException("Exception occurred in creating singleton instance");
        }
    }
    public static StaticBlockSingleton getInstance() {
        return instance;
    }
}

 

 

3. Lazy initializtion

public 메소드에서 인스턴스 생성을 하는데 제약을 두는 방법이다. static 을 통해 변수만 생성한 후에 getInstance를 호출할때 인스턴스를 생성한다. 만약 인스턴스가 있다면 기존의 인스턴스를 활용한다.

 

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

 

하지만 동시에 A, B 쓰레드가 if (instance == null) 에 진입했다면 문제가 될 수 있다. 두개의 쓰레드는 각자 다른 인스턴스를 생성하기 때문에 멀티 쓰레드 환경에서는 문제를 유발하는 방법이다.

 

 

4. Thread Safe Singleton

Lazy 방식에서 서로 다른 쓰레드가 동시접근 했을 때의 단점을 보완한 방법이다. getInstance 메소드 호출시 synchronized를 사용하는 방법이다. synchronized는 하나의 쓰레드만 메소드에 접근할 수 있게한다.

 

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

 

 

하지만 synchronized는 여러 쓰레드가 메소드에 접근할 때 한개의 쓰레드 외에 다른 쓰레드가 접근이 불가능하므로 대기 시간이 발생한다. 따라서 성능 저하를 초래할 수 있다. Double-checked locking 기법을 사용하면 이러한 성능 저하를 막을 수 있다. 

 

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

 

 

5. Bill Pugh Singleton (Lazy Holder) - 권장되는 방법

클래스 안에 내부 클래스를 두는 형태로 클래스를 초기화할때 쓰레드 세이프한 특징을 이용한 방법이다.

외부 클래스인 Singleton 을 로드할때 내부 글래서 SingletonHolder는 로드 되지 않는다.

getInstance 로 SingletonHolder를 호출하면 클래스가 로드되면서 final로 지정하여 값이 재할당 되지 않도록 한다.

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

 

 

 

참고 글

 

Java Singleton Design Pattern Best Practices with Examples | DigitalOcean

 

www.digitalocean.com

 

 

[Java] Singleton Pattern

Java에서 Singleton 패턴이란 ❔ 싱글톤 패턴은 소프트웨어 디자인 패턴 중에 하나로, 하나의 객체만을 생성해 이후에 호출된 곳에서는 생성된 객체를 반환하여 프로그램 전반에서 하나의 인스턴스

choiblack.tistory.com

 

 

[Design Patterns] Singleton Pattern feat. 백기선 강사님

하루 1강씩이라도 듣자는 의지를 계속 실천하고있따!!!! 할수있다!! 잘한다 잘한다 잘한다 자! 오늘의 복습! 시작! Singleton Pattern이 뭐야? - 인스턴스를 오직 한개만 제공하는 클래스! 개념은 알겠

lima1016.tistory.com

 

 

💠 싱글톤(Singleton) 패턴 - 꼼꼼하게 알아보자

Singleton Pattern 싱글톤 패턴은 디자인 패턴들 중에서 가장 개념적으로 간단한 패턴이다. 하지만 간단한 만큼 이 패턴에 대해 코드만 던져주고 끝내버리는 경우가 있어, 어디에 쓰이는지 어떠한 문

inpa.tistory.com

 

반응형