-
[Java] Singleton PatternJava 2022. 1. 3. 23:37
Java에서 Singleton 패턴이란 ❔
싱글톤 패턴은 소프트웨어 디자인 패턴 중에 하나로, 하나의 객체만을 생성해 이후에 호출된 곳에서는 생성된 객체를 반환하여 프로그램 전반에서 하나의 인스턴스만을 사용하게 하는 디자인 패턴을 말한다.
public class Singleton { // Instance private static Singleton instance = new Singleton(); // private construct private Singleton() {} public static Singleton getInstance() { return instance; } }
위 코드는 싱글톤 패턴을 적용한 예제이다. 객체를
static
변수로 설정하여 인스턴스화하지 않고 접근 제한자를private
으로 설정해 직접적인 접근을 불가능하게 한다. 또한, 기본 생성자를private
을 사용하여 생성 불가하게 함으로써getInstance
함수를 통해서만 인스턴스를 얻을 수 있다.Singleton 패턴을 사용하는 이유
오직 하나의 인스턴스만을 사용하게 함으로써 어떤 이점이 있을까 ❔
- 한 번의 객체 생성으로 재사용이 가능하기 때문에 메모리 낭비를 방지할 수 있다.
- 싱글톤으로 생성된 객체는 전역성을 띄기 때문에 다른 객체 간에 공유가 쉽다.
Singleton 패턴의 문제점
- 싱글톤 객체를 사용하는 객체 간의 결합도가 높아진다
싱글톤은 프로그램 전체에서 하나의 객체만을 공통으로 사용하고 있기 때문에 싱글톤 객체를 사용하는 객체 간의 결합도가 높아져 SOLID 중 개방-폐쇄 원칙(Open-Closed Pricipal)에 어긋날 가능성이 있다. - 내부 상태를 변경하기 어렵다.
싱글톤 객체를 수정할 경우 이를 참조하고 있는 모든 값들이 변경되어야 하기 때문에 변경에 유연하게 대처할 수 없다. - 멀티스레드 환경에서 동기화 문제가 발생할 수 있다.
Singleton 패턴 구현 방법
static block
static block을 사용하여 클래스가 로딩될 때 한번만 실행하게 되는 특성을 사용한 방법
문제점: 인스턴스가 사용되는 시점이 아닌 클래스 로딩 시점에 실행이 된다.
public class Singleton { // Instance private static Singleton instance; // private construct private Singleton() {} static { try { instance = new Singleton();} catch(Exception e) { throw new RuntimeException("Create instace fail. error msg = " + e.getMessage()); } } public static Singleton getInstance() { return instance; } }
lazy init
static block을 개선하여 클래스 로딩 시점이 아닌 인스턴스를 요청할 때 생성하는 방법
문제점: 멀티스레드 환경에 취약하다. 특정 스레드가 동시에 getInstance 함수를 호출할 경우 인스턴스가 중복 생성되는 문제가 발생한다.
public class Singleton { // Instance private static Singleton instance; // private construct private Singleton() {} public static Singleton getInstance() { if (instance == null) {instance = new Singleton();} return instance; } }
thread safe + lazy
lazy init에서의 getInstance 함수에 synchronized 키워드를 붙여 동기화 문제를 해결한 방법
문제점: synchronized 키워드는 성능 저하를 발생한다.
public class Singleton { // Instance private static Singleton instance; // private construct private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) {instance = new Singleton();} return instance; } }
Holder
JVM의 클래스 로더 메커니즘과 클래스의 로드 시점을 이용하여 내부 클래스를 통해 생성 시킴으로써 쓰레드 간의 동기화 문제를 해결한 방법
현재 java에서 싱글톤 생성에서 사용하는 대표적인 방법
public class Singleton { // private construct private Singleton() {} /** * static member class * 내부클래스에서 static 변수를 선언해야하는 경우 static 내부 클래스를 선언해야만 한다. * static 멤버, 특히 static 메서드에서 사용될 목적으로 선언 */ private static class InnerSingleton { // 클래스 로딩 시점에서 생성 private static final Singleton uniqueInstance = new Singleton(); } public static Singleton getInstance() { return InnerSingleton.instance; } }
Reference
https://elfinlas.github.io/2019/09/23/java-singleton/
https://tecoble.techcourse.co.kr/post/2020-11-07-singleton/
'Java' 카테고리의 다른 글
[Java] Mutable과 Immutable (1) 2022.01.04 [Java] Serialization과 Deserialization (0) 2022.01.03 [Java] String, StringBuffer, StringBuilder (0) 2022.01.03 [Java] Identity와 Equality (0) 2022.01.03 [Java] Primitive type과 Reference type (0) 2022.01.03