본문 바로가기

디자인패턴

싱글턴 패턴

싱글턴 패턴

클래스 인스턴스를 하나만 만들고, 그 인스턴스로의 전역 접근을 제공한다.

public class Singleton{
    private static Singleton uniqueInstance;

    private Singleton() {}

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

위의 방식은 멀티스레딩 환경에서 getInstance() 메서드의 동기화를 보장해주지 않는다. 따라서 두 스레드가 다른 인스턴스를 return받을 수 있다.

방법 1. synchronized 키워드 사용하기

public class Singleton{
    private static Singleton uniqueInstance;

    private Singleton() {}

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

동기화가 필요한 시점은 메소드를 생성할 때 뿐이다.

방법 2. 처음부터 만들기

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

    private Singleton() {}

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

이 방법을 사용하면 클래스가 로딩될 때 JVM에서 Singleton의 하나뿐인 인스턴스를 생성해준다. JVM에서 인스턴스를 생성하기 전까지 그 어떤 스레드도 uniqueInstance 정적 변수에 접근할 수 없다.

방법3. DCL (Double-Checked Locking)

public class Singleton{
    private volatile static Singleton uniqueInstance;

    private Singleton() {}

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

인스턴스가 생성되어 있는지 확인한 다음 생성되어 있지 않았을 때만 동기화한다. synchronized에 비해 성능이 좋다.

Java volatile이란?

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

왜(Why) 사용할까?

https://nesoy.github.io/assets/posts/20180609/1.png

  • volatile 변수를 사용하고 있지 않는 MultiThread 어플리케이션에서는 Task를 수행하는 동안 성능 향상을 위해 Main Memory에서 읽은 변수 값을 CPU Cache에 저장하게 된다.
  • 만약에 Multi Thread환경에서 Thread가 변수 값을 읽어올 때 각각의 CPU Cache에 저장된 값이 다르기 때문에 변수 값 불일치 문제가 발생할 수 있다.

'디자인패턴' 카테고리의 다른 글

템플릿 메서드 패턴  (0) 2023.12.12
프록시 패턴  (0) 2023.08.28
의존 관계 제어  (0) 2022.08.24