-
Singleton Pattern이란?TECH/Java 2022. 12. 16. 13:55
Singleton Design Pattern
한 클래스에서 여러 객체가 생성될 수 없도록 하는 방법.
Singleton 사용 사례
로깅, 데이터베이스 등
Singleton 클래스가 되려면?
- 반드시 하나의 인스턴스만 갖는다.
- 인스턴스는 글로벌 범위에서 접근할 수 있어야 한다.
Singleton 클래스를 만드는 방법
Eager Initialization 방식, Lazy Initialization 크게 두 방식이 있다.
- Eager Initialization
- 클래스의 실제 사용 여부와 무관하게 객체는 무조건 생성된다. 간단하게 구현할 수 있다는 장점이 있는 반면, 실제로 사용되지 않아도 객체를 생성한다는 단점이 있다.
- Lazy Initialization
- 실제로 객체가 필요한 시점에 생성된다.
Singleton 클래스 구현
Eager Initialization
- 클래스가 로드되는 시점에 JVM에서 static initializer를 실행하기 때문에 thread-safe하다. singleton 객체가 가벼울 경우 이 방법을 사용할 수 있다.
class Foo { private static Foo foo = new Foo(); // 생성자를 통한 객체 생성을 방지하기 위해 생성자를 private으로 설정한다. private Foo() {} public static Foo getInstance() { return foo; } }
Lazy Initialization
version 1
class Foo { private static Foo foo; private Foo() {} public static Foo getInstance() { if (foo == null) foo = new Foo(); return foo; } }
getInstance를 호출하는 시점에 foo 객체가 생성된다.
문제: 여러 스레드에서 동시에 getInstace를 호출할 경우 thread safe하지 않을 수 있다. (여러 foo 객체가 생성될 수 있다.)
version 2
class Foo { public static Foo foo; private Foo() {} public static synchronized Foo getInstance() { if (foo == null) foo = new Foo(); return foo; } }
synchronized 키워드를 활용하여 동시에 한 스레드만 getInstance()를 호출할 수 있도록 한다.
문제: singleton 객체를 생성할 때마다 synchronized를 호출하는 것은 매우 비싼 연산이고, 프로그램의 성능을 저하시킬 수 있다.
하지만, 프로그램 내에서 getInstance()의 성능이 중요하지 않을 경우, 이 방법을 사용하면 매우 간단하고 깔끔한 해결책이 될 수 있다.
version 3
class Foo { private static volatile Foo foo = null; private Foo() {} public static Foo getInstance() { if (foo == null) { // 쓰레드 세이프하게 만들기 위해 synchronized (Foo.class) { // 여러 쓰레드가 위의 단계를 거쳤을 수 있으므로 한번 더 확인한다. if (foo == null) foo = new Foo(); } } return foo; } }
객체를 volatile로 선언하여 singleton 객체가 초기화 될 때 멀티쓰레드에서 객체를 올바르게 제공할 수 있도록 했다.
이 방식은 synchronized를 부를 때마다 발생하는 오버헤드를 현저하게 줄여준다.
출처
https://www.geeksforgeeks.org/singleton-design-pattern-introduction/
'TECH > Java' 카테고리의 다른 글
Managed Language 자바, 자바는 어떻게 힙에서 제거할 객체를 알아낼까? (0) 2022.11.29 Java String Pool이란? (0) 2022.11.17 Mono.zipWith 혹은 Mono.zipWhen이 호출되지 않을 때 (0) 2022.10.23 JVM 메모리 - heap, stack (0) 2022.08.07 Slack api 호출시 account_inactive 에러가 발생하는 경우 (0) 2022.02.05