[디자인 패턴] Singleton

orca·2024년 9월 26일

CS

목록 보기
21/46

Singleton 패턴은 프로그램 내에서 하나의 클래스에 대해 하나의 인스턴스만 존재하도록 보장하는 패턴입니다.

Singleton

  • 하나의 클래스에 대해 단 하나의 인스턴스만 존재하도록 보장하는 패턴
  • 특정 클래스의 인스턴스가 단 한 번만 생성되고, 이후에는 기존에 생성된 객체를 반환하는 방식
  • 사용 예시
    • 애플리케이션 설정값을 관리하는 클래스
    • 데이터베이스 연결풀을 관리하는 클래스

example

public class Singleton {
    private static Singleton instance;

    private Singleton() { }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 외부에서 클래스의 인스턴스를 직접 생성하지 못하도록 생성자를 private 로 선언
  • 인스턴스를 제공하는 메서드는 static 으로 선언되어, 객체가 없어도 호출 가능
  • 하나의 인스턴스를 저장하는 static 변수가 필요함
public class Main {
    public static void main(String[] args) {
        Singleton obj1 = Singleton.getInstance();
        Singleton obj2 = Singleton.getInstance();
        if(obj1 == obj2) {
        	System.out.println("obj1 == obj2");
        } else {
        	System.out.println("obj1 != obj2");
        }

    }
}
  • obj1 과 obj2 는 같은 주소값을 가지므로, "obj1 == obj2" 이 출력됨
  • 유일한 하나의 인스턴스는 처음 Singleton.getInstance() 가 실행될 때 생성된다.

멀티스레드 환경에서 Singleton

멀티스레드 환경에서 동시에 여러 스레드가 getInstance() 를 호출하면, 여러개의 인스턴스가 생성되는 문제가 생길 수 있습니다. 객체를 생성하는 블록에 synchronized 키워드를 걸어 하나의 스레드만 접근할 수 있도록 하면 문제를 해결할 수 있습니다.

  • 유일한 하나의 인스턴스는 처음 Singleton.getInstance() 가 실행될 때 생성됨
    ➡️ 동시에 여러 스레드가 getInstance()를 호출하여 여러 개의 인스턴스가 생성되는 문제 발생 가능

solution

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 키워드로 객체 생성하는 코드 블록을 동기화하여, 한 번에 하나의 스레드만 그 코드 블록을 실행할 수 있도록 함
  • 변수에 volatile 키워드를 사용해 다른 스레드가 instance == null 을 체크할 때 정확한 최신 값을 읽을 수 있게 함

0개의 댓글