티스토리 뷰
디자인 패턴 : Singletone
오늘은 싱글톤 디자인 패턴에 대해 알아보겠다. 싱글톤 디자인은 단 하나의 인스턴스만, 만들어내는 디자인 패턴을 말한다. 인스턴스화 하는 타 객체들과 달리 고정된 영역을 사용하므로 메모리 효율에 그 이점이 있다. 단 하나의 인스턴스만 존재하기 때문에 여러 곳에서 전역적으로 쓸 수 있다.(전역 인스턴스이기 때문이기도 하다.)
자, 그럼 싱글톤은 어떻게 만들까?
단 하나의 인스턴스만을 가지고 있어야 한다는 말은 생성자에 제약을 걸어 두겠다는 의미이다. 가장 간단한 싱글톤의 방법은 다음과 같다.
public class MySingleTone {
private static MySingleTone uniqueInstance = null;
private MySingleTone() {
}
public static MySingleTone getInstance() {
//인스턴스가 없을 때만 생성
if(uniqueInstance ==null) {
uniqueInstance = new MySingleTone();
}
return uniqueInstance;
}
}
위의 코드와 같이 생성자를 닫아 두고 getInstance() 메서드를 통해 제어하는 것이다. 자가참조 변수(=uniqueInstance)가 정적(static) 이므로 클래스 로드시 이미 정적 메모리에 적재된다. 그 상태에서 getInstance()메소드를 통해 인스턴스가 없을 때는 만들어주고, 있다고 한다면 해당 인스턴스의 참조값을 돌려주면 된다.
아 완벽하다!!라고 생각할 수 있지만, 이는 완벽한 싱글톤이라고는 할 수 없다. 우리는 왜 싱글톤을 만들어 쓸까 라는 이유에 대해 다시 올라가 봐야 한다.
싱글톤의 장점은 인스턴스 하나라는 장점도 있지만, 전역 인스턴스라는 또 하나의 큰 장점이 있다. 전역 인스턴스이기에 여러 곳에서 자원을 쓸 수 있다. 하지만, 여러 곳에서 자원을 쓸 수 있기 때문에 위와 같은 코드에서는 문제가 발생할 수 있다. 바로 멀티스레드 환경이다.
여러 개의 쓰레드가 getInstance()를 호출 할 경우, 타이밍에 따라 객체가 여러개 생성될 수도 있다.
이러한 문제를 막기 위해 다음과 같은 방식으로 보완하여 사용하기도 한다.
Synchronized
public class MySingleTone {
private static MySingleTone uniqueInstance = null;
private MySingleTone() {
}
//동기화
public static synchronized MySingleTone getInstance() {
if(uniqueInstance ==null) {
uniqueInstance = new MySingleTone();
}
return uniqueInstance;
}
}
synchronized 키워드를 통해 동기화하는 방법이다. HeadFirstDesign Pattern에서는 synchronized의 극심한 성능 저하를 경고하고 있다. 써도 상관은 없지만, 통상의 100배 정도 성능 저하를 생각하고 쓰면 된다고 얘기한다.
그래서 이러한 성능저하를 또 보안하기 위해 DCL(Double Check Locking) 기법이 등장했다.
DCL
public class MySingleTone {
private volatile static MySingleTone uniqueInstance = null;
private MySingleTone() {
}
public static MySingleTone getInstance() {
if(Objects.isNull(uniqueInstance)) {
synchronized (MySingleTone.class) {
if(Objects.isNull(uniqueInstance)) {
uniqueInstance= new MySingleTone();
}
}
}
return uniqueInstance;
}
}
synchronized 키워드가 메서드 단에서 코드단으로 내려왔고, 동기화된 상태에서 진행한다. 또한 volatile 키워드를 이용하여, cpu cache값이 아닌 main memory 값을 직접 읽어오게 하여, 단일 인스턴스 생성 과정이 올바르게 진행되도록 한다.
싱글톤은 생각보다 자주 보이는 패턴이므로, 그렇게 어렵지 않게 이해할 수 있을 것 같다.
포스팅에 문제가 있거나, 설명이 잘못된 부분 지적 환영합니다.
더 나은 퀄리티의 콘텐츠를 제공할 수 있도록 노력하겠습니다.
읽어주셔서 감사합니다.
'공부 > JAVA' 카테고리의 다른 글
[JAVA] Generic의 이해화 활용 (0) | 2021.10.05 |
---|---|
[JAVA] 업캐스팅(Upcasting) 과 다운캐스팅(Down) (0) | 2021.09.07 |
[JAVA] 오버라이딩(Overriding)과 오버로딩(Overloading) JAVA (0) | 2021.09.06 |
[JAVA] 인터페이스(Interface) JAVA 개념을 부숴주마 (0) | 2021.08.30 |
[JAVA] 기본개념 Stack 영역과 Heap 영역 (0) | 2021.08.25 |
- Total
- Today
- Yesterday
- 브루트포스
- 9019
- java
- 실패일기
- 카카오
- 자바
- Python
- 아기상어미워
- 재귀
- value annotation
- looker core
- 파이썬
- 유클리드-호제법
- dml
- 코딩테스트
- db
- DFS
- 백준
- looker instance 접속
- 프로그래머스 문제정복
- Spring
- 아기상어나쁜상어
- 그래프 탐색
- Database
- BFS
- 프로그래머스
- 플루이드 와샬
- JNDI연동
- 하루 회고
- DP
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |