'구경' 디자인 모델 (7) - 창설 형의 단일 예 모델 (Singleton Pattern)

단일 모델 은 단일 모델 이 라 고도 부 르 는데 자주 사용 하 는 소프트웨어 디자인 모델 이다.이 모드 를 응용 할 때, 단일 대상 의 클래스 는 하나의 실례 만 존재 하도록 보장 해 야 한다.많은 경우 에 전체 시스템 은 하나의 전체적인 대상 만 가지 면 우리 가 시스템 전체의 행 위 를 조율 하 는 데 유리 하 다.예 를 들 어 특정한 서버 프로그램 에서 이 서버 의 설정 정 보 는 한 파일 에 저장 되 어 있 습 니 다. 이 설정 데 이 터 는 하나의 사례 대상 에서 통일 적 으로 읽 은 다음 에 서비스 프로 세 스 의 다른 대상 은 이 사례 대상 을 통 해 이 설정 정 보 를 얻 습 니 다.이런 방식 은 복잡 한 환경 에서 의 배치 관 리 를 간소화 하 였 다.위 키 백과 (WIKIPEDIA)
개인의 이해:
단일 모델 의 개념 은 비교적 간단 하 다. 그의 목적 은 바로 이런 사례 만 나타 나 고 JDBC 작업 류 등에 자주 사용 되 는 것 이다. 내 가 프로젝트 에서 응용 한 곳 은 바로 Dao 층 의 사례 를 얻 는 데 사용 되 는 것 이다. 단일 모델 은 여러 가지 실현 방식 이 있 는데 여기 서 내 가 알 고 있 는 것 은 굶 주 린 식, 게 으 른 식, 매 거, 정태 내부 류 가 있다.이번 정리 과정 이 다행히 단일 모델 의 지식 을 많이 넓 혔 기 때문이다.
다음은 실제 예 를 살 펴 보 자.
게으름뱅이 식
</pre><span style="font-size:18px;"><span style="font-size:12px;"></span></span><pre name="code" class="java">public class Singleton01 {

	private static Singleton01 singleton = null;
	
	private Singleton01(){}
	
	public static Singleton01 getInstance(){
		
		if(singleton == null)
			singleton = new Singleton01();
		
		return singleton;
	}
}

스 레 드 가 안전 하지 않 습 니 다. 여러 스 레 드 가 getInstance 방법 을 동시에 호출 할 때 singleton 이 null 인 것 을 감지 하고 대상 을 만 들 기 시 작 했 습 니 다. 이 때 는 하나의 인 스 턴 스 가 아 닌 여러 개의 인 스 턴 스 를 만 듭 니 다.
public class Singleton02 {

	private static Singleton02 singleton = null;
	
	private Singleton02(){}
	
	public synchronized static Singleton02 getInstance(){
		
		if(singleton == null)
			singleton = new Singleton02();
		
		return singleton;
	}
}

이 예 는 스 레 드 가 안전 하고 여러 스 레 드 가 동시에 호출 될 때 도 여러 개의 대상 인 스 턴 스 를 만 들 지 않 지만 효율 적 이지 않 습 니 다. 여러 스 레 드 가 순서대로 이 방법 을 실행 해 야 합 니 다.
public class Singleton03 {

	private static Singleton03 singleton = null;
	
	private Singleton03(){}
	
	public static Singleton03 getInstance(){
		
		if(singleton == null)
			synchronized (Singleton03.class) {
				
				if(singleton == null){
					singleton = new Singleton03();
				}
			}		
		
		return singleton;
	}
}

이런 방식 은 Double Check (이중 검사) 라 고 불 리 며 비교적 전형 적 인 디자인 인 데 왜 두 번 을 해 야 합 니까?먼저 바깥 의 판단 은 대상 이 이미 생 성 된 것 을 피 한 후에 생 성 대상 을 동기 화하 지 않 아 도 된다 는 것 이다. 두 번 째 는 첫 번 째 로 인 스 턴 스 를 만 들 지 않 았 을 때 여러 스 레 드 가 기다 리 고 있 고 이 럴 때 빈 판단 이 필요 하 다 는 것 이다.뒤에서 기다 리 는 현장 이 들 어 온 후에 다시 인 스 턴 스 를 만 드 는 것 을 방지 합 니 다.
다른 사람의 글 을 참고 했다 [1]:
singleton = new Singleton () 은 원자 조작 이 아니 라 JVM 에서 크게 세 가지 일 을 했 습 니 다.
1. 인 스 턴 스에 메모리 할당.
2. 구조 함 수 를 통 해 구성원 변 수 를 초기 화 합 니 다.
3. 인 스 턴 스 를 분 배 된 메모리 공간 으로 가 리 킵 니 다.(인 스 턴 스 를 실행 하면 null 이 아 닙 니 다).
그러나 JVM 컴 파일 러 에 명령 어 정렬 최적화 가 존재 합 니 다. 최종 실행 순 서 는 1 - 2 - 3 또는 1 - 3 - 2 입 니 다. 1 - 3 - 2 라면 3 실행 이 완료 되 고 2 실행 전에 스 레 드 A 가 스 레 드 B 에 의 해 중단 되면 인 스 턴 스 가 비어 있 지 않 고 스 레 드 B 가 인 스 턴 스 로 직접 돌아 갑 니 다. 이때 직접 사용 하면 오류 가 발생 합 니 다.
제 시 된 해결 방법 (volatile 키워드 차단 재 정렬 사용) 은:
public class Singleton03 {

	private volatile static Singleton03 singleton = null;
	
	private Singleton03(){}
	
	public static Singleton03 getInstance(){
		
		if(singleton == null)
			synchronized (Singleton03.class) {
				
				if(singleton == null){
					singleton = new Singleton03();
				}
			}		
		
		return singleton;
	}
}

굶 주 린 사람 식
public class Singleton04 {

	private static final Singleton04 singleton = new Singleton04();
	
	private Singleton04(){
	}
	
	public static Singleton04 getInstance(){
		return singleton;
	}
}

이러한 방식 은 스 레 드 가 안전 하지만 부족 한 것 은 getInstance 방법 을 호출 하지 않 아 도 그의 인 스 턴 스 가 생 길 수 있다 는 것 이다.이전의 게으름뱅이 식 방식 은 게으름뱅이 사상 을 싣 고 필요 할 때 만 드 는 것 이 었 다.
정적 내부 클래스
public class Singleton05 {

	private static class Singleton{
		private static final Singleton05 instance = new Singleton05();
	}
	
	private Singleton05(){
	}
	
	public Singleton05 getInstance(){
		return Singleton.instance;
	}
}

정적 내부 류 의 방식 을 사 용 했 습 니 다. 개인 적 인 정적 내부 류 는 외부 에 접근 할 수 없고 굶 주 린 식 과 유사 한 형식 입 니 다. 그러나 이 를 바탕 으로 개선 되 었 습 니 다. 굶 주 린 식 은 사용 하 는 내부 속성 입 니 다. 이것 은
사용 하 는 정적 내부 클래스 의 상수 입 니 다.
매 거
신 같은 디자인, 매 거 진 단일 모델 을 실현 하 는 몇 가지 이유:
1. 자유 서열 화
2. 스 레 드 보안
3. 하나의 실례 만 있 을 것 을 보증한다.
public enum Singleton06 {

	INSTANCE;
	
	private Singleton06(){
	}
	
	public void print(){
		System.out.println("Enum Singleton!");
	}
}

호출:
Singleton06.INSTANCE.print();

코드 다운로드
다운로드 코드
레 퍼 런 스
【1】 http://wuchong.me/blog/2014/08/28/how-to-correctly-write-singleton-pattern/

좋은 웹페이지 즐겨찾기