본문 바로가기
개발용어

디자인패턴 - 싱글턴 패턴, singleton pattern

by devscb 2022. 10. 15.
반응형

디자인패턴 - 싱글턴 패턴


 싱글턴패턴이란?


싱글턴 패턴은 디자인패턴에서 가장 단순한 생성패턴 입니다.
이 패턴은 단일 객체만 생성되도록 하면서 객체를 생성하는 역할을 하는 단일 클래스를 포함합니다.
이 클래스는 클래스의 객체를 인스턴스화할 필요 없이, 직접 액세스할 수 있는 유일한 객체에 액세스할 수 있는 방법을 제공합니다.

 싱글턴패턴 UML


싱글턴 패턴 UML은 아래와 같습니다.
내부에 Singleton의 인스턴스가 있으며,
생성자는 private하게, getInstance 메소드로 instance를 리턴하는 패턴입니다.
instance는 Singleton 클래스에서 단 하나만 존재합니다.


이 클래스 외부에서 Singleton 패턴을 적용한 Singleton클래스를 생성하려고 해도
새로 생기지 않고, 동일한 object만 결과값을 리턴하게 됩니다.



 싱글턴패턴 소스코드


다음으로 코드를 살펴보겠습니다.
코드를 보시면 좀 더 명확하게 이해가 될것입니다.
Singleton 클래스는 항상 instance 객체만 접근하여 사용할 수 있습니다.


public class Singleton {
    // 단 1개만 존재해야 하는 객체의 인스턴스, static 으로 선언
    private static Singleton instance;

    // private 접근자로 외부에서 객체 생성을 막음
    private Singleton() {}

    // 외부에서는 getInstance() 로 instance 를 사용
    public static Singleton getInstance() {
      // instance 가 null 이면 생성, 아니라면 기존의 instance를 리턴
      if (instance == null){
          instance = new Singleton();
      }
      return instance; 
    } 
}




 멀티쓰레드 환경에서의 싱글턴 패턴의 문제


멀티쓰레드 환경에서는 앞서 본 싱글턴 패턴이 정상적으로 동작하지 않습니다.

예를 들어 아래와 같은 타이밍으로 실행이 된다면 정상적으로 동작하지 않을것입니다.

 


thread1이 instance = new Singleton()으로 객체를 생성하기 직전, context switching이 일어나서,
therad2에서 if(instance == null) 을 만나게 되면, 아직 객체가 생성되기 전이기에 if문 안 block을 실행합니다.
그러면 instance가 생성되고, 다시 thread1으로 context swithcing이 발생하면 thread1에서도 또 다른 객체를 생성하게 됩니다.



 LazyHolder 기법으로 구현한 싱글턴


앞서 본 이유로 인해, LazyHolder 라는 방법이 있습니다.
바로 코드를 보겟습니다.


public class Singleton {
    
    private Singleton() {}

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

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


클래스의 static 변수는 클래스를 로딩할 때 초기화되는 것을 이용한 기법입니다.
먼저, Singleton 클래스가 로딩될 때, LazyHolder 클래스를 초기화하지 않습니다.
getInstance 메서드가 호출될 때 LazyHolder 클래스가 JVM에서 로딩되며 초기화가 진행됩니다.
이 때, LazyHolder라는 클래스의 로딩은 Thread safe를 보장합니다.
Thread safe를 보장하는것은 자바 언어 명세서(Java Language Specification, JLS)에 의해 보장이 되며,
어떠한 자바버전을 쓰더라도 해당 방식을 사용할 수 있습니다.
* 참고 JSL 12.4.2 - https://docs.oracle.com/javase/specs/jls/se17/html/jls-12.html#jls-12.4.1


이 글에서 소개하지 않았지만, synchronized를 이용한 방법도 있으나,
overhead가 크게 발생하기때문에, 일반적으로 LazyHolder방식을 많이 사용합니다.



 싱글턴패턴은 언제 쓰는가


싱글턴패턴은 아래 조건일때 싱글턴 패턴 사용을 고려할 수 있습니다.
- 공유 리소스에 대한 동시 액세스를 제어합니다.
- 리소스에 대한 접근은 시스템의 여러 모듈에서 요청됩니다.
- 오직 하나의 인스턴스만 있을 수 있습니다.

프로그램의 설정정보, database connection, file 매니저, 하드웨어제어
등을 다룰 때 사용합니다.


#싱글턴,#패턴,#디자인패턴,#싱글턴패턴,#싱글톤,#싱글톤패턴,#singleton,#pattern,#singletonpattern,#designpattern,#lazyholder

 

https://devscb.com/post/132

 

Design pattern - singleton pattern

Design pattern - Singleton pattern What is a singleton pattern?The singleton pattern is the simplest creation pattern among design patterns.This pattern involves a single class responsible for creatin

devscb.com

 

728x90
반응형

댓글