개발바닥

싱글턴 패턴 본문

개인 공부/자바 디자인 패턴

싱글턴 패턴

라이언 2019. 3. 17. 21:36
반응형

싱글턴 패턴이란?


인스턴스가 오직 하나만 생성되는 것을 보장하고 어디에서든 이 인스턴스에 접근할 수 있도록 한다.

보통 애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 인스턴스를 만들어서 사용하는 디자인 패턴이다.

싱글턴 클래스에 getInstance 메서드를 통해 객체 생성을 요청하면 이미 객체가 생성된 경우에는 객체를 반환하고, 처음으로 생성하는 경우에는 생성자를 호출해 객체를 생성한다.


하나의 인스턴스만을 유지하기 위해 인스턴스 생성에 특별한 제약을 걸어둬야 한다.

new를 실행할 수 없도록 생성자에 private 접근 제어자를 지정하고, 유일한 단일 객체를 반환할 수 있도록 정적 메소드를 지원해야 한다.

또한 유일한 단일 객체를 참조할 정적 참조변수가 필요하다.



싱글턴 패턴을 사용하는 이유


고정된 메모리 영역을 얻으면서 한번의 new로 인스턴스를 사용하기 때문에 메모리 낭비를 방지할 수 있고, 싱글톤으로 만들어진 클래스의 인스턴스는 전역 인스턴스이기 때문에 다른 클래스의 인스턴스들이 데이터를 공유하기 쉽다.


흔히 자주 사용되는 사례가 DBCP(DataBase Connection Pool)처럼 공통된 객체를 여러개 생성해서 사용해야하는 상황에서 많이 사용된다.

(쓰레드풀,캐시,대화상자,사용자 설정 등등)


주의할점은 싱글턴 인스턴스가 너무 많은 일을 하거나 많은 데이터를 공유시킬 경우 다른 클래스의 인스턴스들 간에 결합도가 높아져 "OCP"을 위배하게 된다.

(*OCP (개방-폐쇄 원칙 : 기존에 코드를 변경하지 않고 새로운 기능을 추가할 수 있도록 설계)


멀티쓰레드에서 안전한 싱글턴 클래스,인스턴스 만드는 방법에 대해서 알아보겠습니다.

(https://jeong-pro.tistory.com/86  블러그 참고하였습니다.)



1.Thread safe lazy initialization (게으른 초기화)




제가 일반적으로 알고 있던 싱글턴 패턴 구현 방법으로 private static으로 인스턴스 변수를 만들고 private 생성자로 외부에서 생성을 막았으며 synchronized 키워드를 사용해서 thread-safe하게 만듭니다. 하지만 synchronized 특성상 비교적 큰 성능저하가 발생하므로 권장하지 않는 방법입니다.



2. Thread safe lazy initialization + Double-checked locking


Thread safe lazy initialization (게으른 초기화)의 성능저하를 완화시키는 방법


 



getInstance()에 synchronized를 사용하는 것이 아니라 첫 번째 if문으로 인스턴스의 존재여부를 체크하고 두 번재 if문에서 다시 한번 체크할 때 동기화 시켜서 인스턴스를 생성하므로 thread-safe하면서도 처음 생성 이후에 synchronized 블럭을 타지 않기 때문에 성능저하를 완화했다.



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


클래스안에 클래스(Holder)를 두어 JVM 의 Class loader 매커니즘과 class가 로드되는 시점을 이용한 방법



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

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

반응형

'개인 공부 > 자바 디자인 패턴' 카테고리의 다른 글

스트래티지 패턴  (0) 2019.02.10
디자인 패턴  (0) 2019.02.01
SOLID 원칙  (0) 2019.01.30
자바 추상화  (1) 2019.01.30
모델링  (0) 2019.01.30
Comments