Singleton - LazyHolder

Singleton - LazyHolder

소프트웨어 디자인 패턴에서 싱글턴 패턴을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다

 

Singleton 구현방법

 

  1. 기본적인 Singleton 구현방법 (Thread-Safe)

getInstance method 로 인스턴스로 가져올때 마다 synchronized 키워드로 인해 동기화 과정에서 Lock으로 인한 성능 저하가 생길 수 있음

이리하여 DLC(Double-Checked-Locking) Singleton 으로 진화하게 됨

 

  1. DLC(Double-Checked-Locking) Singleton

DLC Singleton과 같은 경우는 멀티쓰레드 환경에서 컴파일러에 따라 재배치(reordering)문제를 야기할 수도 있다는데,

어느 블로그가 정리한 내용을 빌려오자면

소스코드가 논리적으로 문제가 없지만 컴파일러에 따라서 재배치(reordergin)문제를 야기한다.

위에 소스가 컴파일 되는 경우 인스턴스 생성은 아래와 같은 과정을 거치게 된다.

멀티쓰레드 환경일 경우 각 스레드마다 동일 메모리를 공유하는 것이 아닌 별도 메모리 공간에서 변수를 읽어온다. 이런 경우 각 스레드마다 동일한 변수의 값을 다르게 기억할 수 있다. 만약 Thread A가 인스턴스 생성을 위해서 instance = some_place;를 수행하는 순간 Thread B가 Test.getInstace()를 호출하게 되면 아직 실제로 인스턴스가 생성되지 않았지만, Thread B는 instance == null 의 결과가 false로 리턴되어 문제를 야기하게 된다.

 

  1. Initialization on demand holder idiom (holder에 의한 초기화)

개발자가 직접 동기화 문제에 대해 코드를 작성하고 문제를 회피하려 한다면 프로그램 구조가 그 만큼 복잡해지고 비용 문제가 생길 수 있고 특히 정확하지 못한 경우가 많다.(100%가 아닐수 있음)

그런데 이 방법은 JVM의 클래스 초기화 과정에서 보장되는 원자적 특성을 이용하여 싱글턴의 초기화 문제에 대한 책임을 JVM에 떠넘긴다.

holder안에 선언된 instance가 static이기 때문에 클래스 로딩시점에 한번만 호출될 것이며 final을 사용해 다시 값이 할당되지 않도록 만든 방법.

가장 많이 사용하고 일반적인 Singleton 클래스 사용 방법이다.

 

'Java' 카테고리의 다른 글

2. 객체지향 언어 특징  (0) 2018.07.26
1. Java란  (0) 2018.07.26
2. 변수자료형연산자  (0) 2017.03.16
1. 기본 입출력  (0) 2017.03.16

+ Recent posts