자바 디자인 모델 의 단일 예 모드 상세 설명
소스 코드 전체 프로젝트 는 디자인 모델 뿐만 아니 라 다른 자바 SE 지식 도 있 습 니 다.스타,포크 를 환영 합 니 다.
단일 모드 UML 그림
단일 모드 의 관건
위의 UML 그림 을 통 해 우 리 는 단일 모델 의 특징 이 다음 과 같다 는 것 을 알 수 있다.
1.구조 기 는 개인 적 인 것 으로 외부 클래스 호출 구조 기 를 허용 하지 않 습 니 다.
2.외부 접근 을 위 한 방법 을 제공 합 니 다.이 방법 은 단일 사례 의 인 스 턴 스 를 되 돌려 줍 니 다.
어떻게 단일 모델 을 실현 합 니까?
위 에서 이미 단일 모델 의 관건 을 제 시 했 기 때문에 우리 의 실현 은 위의 두 가지 만 만족 시 키 면 된다.그러나 단일 모델 의 실현 방식 이 비교적 느슨 하기 때문에 서로 다른 실현 방식 에 서로 다른 문제 가 있 을 수 있다.우 리 는 단일 모델 의 실현 에 대해 분 류 를 해서 어떤 다른 실현 방식 이 있 는 지 볼 수 있다.
1.단일 대상 의 생 성 시기 에 따라 굶 주 린 사람 모델 과 게으름뱅이 모델 로 나 눌 수 있다.굶 주 린 사람 은 클래스 를 불 러 올 때 대상 을 만 드 는 것 을 말한다.그러나 대상 을 만 드 는 데 자원 이 소모 되 어 클래스 로드 가 느 릴 수 있 지만 대상 을 얻 는 속도 가 빠르다 는 것 이 장점 입 니 다.이미 만 들 어 졌 기 때 문 입 니 다.게 으 른 사람 은 굶 주 린 사람 에 비해 하나의 대상 으로 돌아 가 야 할 때 대상 을 만 들 고 클래스 를 불 러 올 때 초기 화 되 지 않 으 며 좋 은 점 과 단점 도 말 하지 않 는 다.
2.스 레 드 안전 실현 여부 에 따라 일반 게으름뱅이 모델 과 같은 스 레 드 안전 하지 않 은 쓰기,굶 주 린 남자 모델,잠 금 된 게으름뱅이 모델 을 이중 으로 검사 하고 정적 내부 류 나 매 거 진 류 등 을 통 해 이 루어 진 스 레 드 안전 한 쓰기 로 나 눌 수 있다.
스 레 드 가 안전 하지 않 은 단일 모드
public class SimpleSingleton {
private static SimpleSingleton simpleSingleton;
private SimpleSingleton(){
}
public static SimpleSingleton getInstance(){
if (simpleSingleton == null) {
simpleSingleton = new SimpleSingleton();
}
return simpleSingleton;
}
}
우선 게으름뱅이 모델 의 실현 임 을 알 수 있다.getInstance 에 있 을 때 만 하나의 대상 을 만 들 수 있 기 때문이다.그런데 왜 그 는 스 레 드 가 안전 하지 않 은 것 일 까?2 개의 스 레 드 가 동시에 if(simpleSingleton==null)에 들 어 갈 수 있다 는 판단 이 동시에 simpleSingleton 대상 을 만 들 었 기 때문이다.DCL 게으름뱅이 모드
위의 방법 은 스 레 드 가 안전 하지 않 은 문제 가 존재 한 다 는 것 을 알 수 있 습 니 다.우 리 는 동기 화 키워드 synchronized 로 스 레 드 안전 을 실현 할 수 있 습 니 다.우 리 는 먼저 점차적으로 분석 하고 먼저 synchronized 로 위의 게으름뱅이 모델 을 고 칩 니 다.코드 는 다음 과 같 습 니 다.
public class DCLSingleton {
private static DCLSingleton singleton;
private DCLSingleton(){
}
public synchronized static DClSingleton getSingleton(){
if (singleton == null) {
singleton = new DCLSingleton();
}
return singleton;
}
}
이렇게 하면 두 개의 스 레 드 가 동시에 이 방법 을 실행 하지 않 을 것 이 라 고 효과적으로 보장 할 수 있 지만 이 효율 도 너무 낮 습 니 다.인 스 턴 스 를 만 든 후에 인 스 턴 스 대상 을 얻 을 때마다 동기 화 를 해 야 하기 때문에 synchronized 의 동기 화 보증 대가 가 비교적 크기 때문에 이 를 바탕 으로 개조 할 수 있 습 니 다.이미 만들어 진 후에 동기 화 할 필요 가 없습니다.우 리 는 다음 과 같은 형식 으로 바 꿀 수 있 습 니 다.
public static DCLSingleton getSingleton(){
if (singleton == null) {
synchronized (DCLSingleton.class) {
if (singleton == null) {
singleton = new DCLSingleton();
}
}
}
return singleton;
}
다른 코드 는 변 하지 않 고 이 방법 만 봅 니 다.이 방법의 이중 if(singleton==null)는 스 레 드 안전 을 효과적으로 보장 할 수 있 습 니 다.예 를 들 어 두 스 레 드 가 이 방법 에 동시에 들 어 갈 때 첫 번 째 if 는 둘 다 들 어 갑 니 다.아래 의 코드 이지 만 동기 코드 블록 에 부 딪 히 면 한 개 만 먼저 들 어가 고 들 어 갈 때 계속 판단 하고 다시 빈 것 으로 판단 해 야 진정 으로 대상 을 만 들 수 있 습 니 다.만약 에 진행 하지 않 으 면 두 번 째 판단 은 첫 번 째 로 들 어 온 스 레 드 에 있어 대상 을 만 들 었 지만 두 번 째 스 레 드 는 그 다음 에 대상 을 만 드 는 작업 을 수행 할 것 입 니 다.첫 번 째 스 레 드 가 성공 적 으로 만 들 어 졌 는 지 모 르 기 때 문 입 니 다.따라서 두 차례 의 판정 이 필요 하 다.그런데 정말 이렇게 간단하게 라인 안전 을 보장 한 건 가요?우 리 는 이 과정 을 자세히 분석 해 보 자.singleton=new DCLSingleton();이 코드 는 실제로 세 개의 조작 이다.
1.DCLSingleton 인 스 턴 스 에 메모리 할당
2.DCLSingleton()의 구조 함 수 를 호출 하여 구성원 필드 초기 화
3.singleton 대상 을 분 배 된 메모리 공간 으로 가리킨다.
JDK 1.5 이전 에는 위의 3 개의 실행 순서 가 일정 하지 않 아 1-2-3 또는 1-3-2 일 수 있 었 다.1-3-2 라면 첫 번 째 스 레 드 가 세 번 째 단 계 를 실행 한 후에 두 번 째 스 레 드 가 즉시 실행 되 지만 아직 초기 화 되 지 않 아 사용 할 때 오류 가 발생 합 니 다.JDK 1.5 이후 에 우 리 는 volatile 키워드 로 이 1-2-3 의 순 서 를 보장 할 수 있다.따라서 getSingleton()방법 을 위의 모양 으로 바 꾸 는 것 외 에 private static DCLSingleton singleton 도 필요 합 니 다.private static volatile DCLSingleton singleton 으로 바 꾸 기;이렇게 하면 스 레 드 동기 화 게으름뱅이 쓰기 의 단일 예 모델 을 진정 으로 보장 한다.
굶 주 린 자의 서법
굶 주 린 사람 이 쓰 는 방법 은 많은 변형 이 있 지만 어떤 변형 이 든 스 레 드 의 안전 을 보장 할 수 있 습 니 다.굶 주 린 사람 이 쓰 는 방법 은 클래스 로 딩 할 때 대상 의 초기 화 를 완 성 했 기 때 문 입 니 다.클래스 로 딩 은 그들 이 타고 난 스 레 드 안전 을 보장 합 니 다.흔히 볼 수 있 는 2 중 굶 주 린 남자 의 글 씨 를 보 여 드 리 겠 습 니 다.
public class HungrySingleton {
private static final HungrySingleton singleton = new HungrySingleton();
private HungrySingleton(){
}
public static HungrySingleton getSingleton(){
return singleton;
}
}
public class HungrySingleton {
private static final HungrySingleton singleton = new HungrySingleton();
private HungrySingleton(){
}
// public static HungrySingleton getSingleton(){
// return singleton;
// }
}
이 두 가지 초기 화 사례 의 대상 위 는 모두 일치 하 며 final 을 통 해 대상 을 확보 하 는 유일한 것 이다.다른 것 은 단일 대상 을 호출 하 는 방식 이다.첫 번 째 는 getSingleton()을 통 해,두 번 째 는 클래스.클래스 변 수 를 통 해.정적 내부 클래스 구현 단일 모드
이중 검사 잠 금(DCL)은 단일 모드 를 실현 합 니 다.스 레 드 가 안전 하지 않 은 문 제 를 해결 하고 자원 의 게 으 름 로드 를 확보 하지만 필요 할 때 만 정례 화 된 작업 을 할 수 있 습 니 다.그러나 어떤 경우(예 를 들 어 JDK 가 1.5 보다 낮 음)DCL 이 효력 을 잃 기 때문에 간결 하고 게 으 른 로드 방법 으로 단일 모델 을 실현 하 는 방법 이 있다.쓰 는 방법 은 다음 과 같다.
public class StaticSingleton {
private StaticSingleton(){
}
public static final StaticSingleton getInstance(){
return Holder.singleton;
}
private static class Holder{
private static final StaticSingleton singleton = new StaticSingleton();
}
}
정적 내부 클래스 의 형식 을 통 해 단일 클래스 의 초기 화 를 실현 합 니 다.그 특성 은 ClassLoader 를 통 해 단일 대상 을 확보 하 는 유일한 것 입 니 다.그러나 이것 은 게 으 른 로 딩 입 니 다.Holder 클래스 가 호출 될 때,즉 getInstance 가 호출 될 때 만 Holder 클래스 를 불 러 와 서 대상 을 만 들 수 있 기 때 문 입 니 다.매 거 클래스 구현 단일 모드
코드 직접 보기:
public enum EnumSingleton {
SINGLETON;
public void doSometings(){
}
}
사용 할 때 는 EnumSingleton.SHINGLETON.doSomethings()를 통 해 직접 사용 합 니 다.매 거 류 의 타고 난 특성 은 두 개의 인 스 턴 스 가 없 을 것 을 보장 하고 첫 번 째 방문 할 때 만 실례 화 되 며 게 으 른 로 딩 상황 입 니 다.정말 새로운 대상 을 다시 만 들 지 않 을까요?
일반적인 단일 클래스 의 getInstance()방법 을 호출 하 는 상황 에서 스 레 드 안전 한 쓰기 방법 을 사용 하면 새로운 대상 을 만 들 지 않 지만 자바 는 많은 특이 한 기술 과 사용 을 제공 합 니 다.아래 의 사용 은 일반적인 단일 사례 를 파괴 할 수 있 습 니 다.
단일 모드 는 두 가지 비교적 적합 한 사용 장면 이 있다.
첫 번 째 는 특정한 대상 을 만 드 는 데 필요 한 대가 가 비교적 크다 는 것 이다.빈번 한 창설 과 소각 대상 으로 인해 발생 하 는 자원 에 대한 낭 비 를 피하 기 위해 단일 모델 을 사용 하 는 것 을 고려한다.
두 번 째 는 이 대상 이 하나 밖 에 없어 야 한 다 는 것 이다.예측 할 수 없 는 오류 나 프로그램의 혼란 을 초래 할 수 있다.예 를 들 어 하나의 번호 생 성기,하나의 캐 시 등 이다.
사용 하 는 단일 모드 에 대해 이해 해 야 할 로 딩 자원 은 굶 주 린 사람 으로 쓰 는 것 입 니 다.안 드 로 이 드 응용 프로그램 에서 많은 대상 이 시작 할 때 바로 사용 해 야 합 니 다.예 를 들 어 시작 할 때 카메라 설정 의 클래스 관리 미리 보기 그림 의 cache 류 등 입 니 다.즉각 적 으로 필요 하지 않 거나 일관 되 게 응용 되 지 않 으 면 굶 주 린 사람 이 쓰 는 방법 을 사용 할 필요 가 없고 게으름뱅이 가 쓰 는 방법(DCL 또는 정적 내부 류 실현)이라는 두 가 지 는 일반적인 상황 에서 문제 가 발생 하지 않 는 다 는 것 을 고려 할 수 있다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.