디자인패턴 - 싱글턴 패턴
싱글턴패턴이란?
싱글턴 패턴은 디자인패턴에서 가장 단순한 생성패턴 입니다.
이 패턴은 단일 객체만 생성되도록 하면서 객체를 생성하는 역할을 하는 단일 클래스를 포함합니다.
이 클래스는 클래스의 객체를 인스턴스화할 필요 없이, 직접 액세스할 수 있는 유일한 객체에 액세스할 수 있는 방법을 제공합니다.
싱글턴패턴 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
'개발용어' 카테고리의 다른 글
gRPC란, protobuf란, Java gRPC 예제 코드, grpc단점, grpc java code example (1) | 2023.06.05 |
---|---|
DIME이란, DIME 예제 코드 Java, DIME 예제 코드 C#, MIME DIME 비교 (0) | 2022.10.16 |
SOLID 원칙 - 의존성 역전 원칙, DIP (Dependency Inversion Principle) (0) | 2022.10.15 |
CSRF란, CSRF 동작원리, CSRF 방어방법 (0) | 2022.08.03 |
MVC패턴이란, Spring MVC란, Spring MVC 장점, Spring MVC (0) | 2022.07.06 |
댓글