자바 디자인 모델-단일 모델 실현 방법 상세 설명

단일 모드 는 생 성 유형 에 자주 사용 되 는 소프트웨어 디자인 모델 에 속한다.단일 모드 를 통 해 만 든 클래스 는 현재 프로 세 스 에서 하나의 인 스 턴 스 만 있 습 니 다(필요 에 따라 하나의 스 레 드 에서 하나의 인 스 턴 스 에 속 할 수도 있 습 니 다.예 를 들 어 스 레 드 컨 텍스트 에서 만 같은 인 스 턴 스 를 사용 할 수 있 습 니 다).전체 소프트웨어 시스템 에서 특정한 유형 에 하나의 대상 인 스 턴 스 만 존재 할 수 있 도록 일정한 방법 을 취하 고 이 유형 은 대상 인 스 턴 스 를 얻 는 방법(정적 방법)만 제공 하 는 것 이다.
클래스 는 메모리 에 하나의 인 스 턴 스 대상 만 존재 합 니 다.
굶 주 린 사람 식
이른바 굶 주 린 한식 이란 바로 이러한 실례 화 를 직접 만 든 다음 에 private 민영화 로 대외 적 으로 정태 적 인 방법 으로 만 노출 하 는 것 이다.
정적 변수
순서
구조 기 민영화
클래스 의 내부 창설 대상정 지 된 공공 방법 을 밖으로 노출 하 다.
장점.
결점.
쓰기 가 간단 하고 클래스 를 불 러 올 때 실례 화 를 완성 하여 라인 동기 화 문 제 를 피 할 수 있 습 니 다
클래스 불 러 올 때 실례 화 를 완 료 했 습 니 다.LazyLoading 의 효과 에 이 르 지 못 했 습 니 다.이 실례 를 사용 하지 않 으 면 메모리 낭비 가 발생 할 수 있 습 니 다

class Singleton {
	//      
	private Singleton() {	
	}
	//        
	private final static Singleton instance = new Singleton();
	//         
	public static Singleton getInstance() {
		return instance;
	}
}
정적 코드 블록
정적 코드 블록 에 클래스 의 실례 화 를 쓰 는 방법 은 기본적으로 같다.

class Singleton {  //     
	//      
	private Singleton() {}
	//        
	private  static Singleton instance;
	static { //        ,      
		instance = new Singleton();
	}
	//         
	public static Singleton getInstance() {
		return instance;
	}
}
테스트 코드(뒤에 이 테스트 코드 를 사용 할 수 있 습 니 다.캡 처 를 군말 하지 않 고 직접 시도 할 수 있 습 니 다):

public static void main(String[] args) {
		Singleton instance1 = Singleton.getInstance();
		Singleton instance2 = Singleton.getInstance();
		System.out.println(instance1 == instance2);
		System.out.println("instance1.hashCode=" + instance1.hashCode());
		System.out.println("instance2.hashCode=" + instance2.hashCode());
	}
在这里插入图片描述
게으름뱅이 식
게으름뱅이 식 이란 호출 이 필요 할 때 클래스 를 만 드 는 실례 화 이다.
스 레 드 가 안전 하지 않 습 니 다.
게 으 른 로드 효 과 를 얻 었 지만 단일 스 레 드 에서 만 사용 할 수 있 습 니 다.다 중 스 레 드 는 안전 하지 않 습 니 다.여러 스 레 드 가 동시에 인 스 턴 스 가 비어 있다 고 판단 할 때 해당 하 는 사례 화 여러 대상 이 있 기 때 문 입 니 다.

class Singleton { //     
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {  //         ,   
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
스 레 드 보안
위의 스 레 드 가 안전 하지 않 습 니 다.자 물 쇠 를 잠 그 면 되 잖 아 요.synchronized 키 워드 를 사용 하 세 요.
이렇게 하면 스 레 드 안전 을 해 결 했 지만 실제 예화 작업 은 한 번 만 하고 인 스 턴 스(즉 getInstance)를 얻 는 작업 은 여러 번 이 며 호출 방법 을 동기 화하 면 효율 이 크게 떨어진다.

class Singleton { //    
    private static Singleton instance;
    private Singleton() {}
    //synchronized    
    public static synchronized Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
이중 검사
위의 코드 효율 이 낮 으 면 동기 화 전에 실례 화 되 었 는 지 판단 하면 되 지 않 습 니까?실례 화 되 지 않 으 면 동기 화 방법 new 를 사용 합 니 다.그렇지 않 으 면 바로 return 하면 됩 니 다.이른바 이중 검사 다.
키워드 volatile 을 사용 하여 명령 의 정렬 을 방지 해 야 합 니 다.volatile 키 워드 를 사용 하지 않 으 면 스 레 드 가 안전 하지 않 은 상황 과 마찬가지 로 if 에서 동시 다발 이 있 을 것 이 라 고 판단 합 니 다.

class Singleton { //    
	private static volatile Singleton instance;
	private Singleton() {}
	public static synchronized Singleton getInstance() {
		if(instance == null) { //       
			synchronized (Singleton.class) {
				if(instance == null) {
					instance = new Singleton();
				}
			}
		}
		return instance; //    return
	}
}
이렇게 하면 게 으 른 로드 를 실현 할 뿐만 아니 라 스 레 드 안전 도 보장 할 수 있다.
정적 내부 클래스
정적 내부 클래스 는 외부 클래스 에서 불 러 올 때 예화 되 지 않 고 호출 할 때 불 러 오고 예화 되 며 JVM 은 불 러 올 때의 스 레 드 안전성 을 확보 합 니 다.게 으 른 로드 와 스 레 드 안전 도 보장 되 며 자체 테이프 판 이중 검사 와 같 습 니 다.

class Singleton {
	private static volatile Singleton instance;
	private Singleton() {}
	//     ,        :Singleton
	private static class SingletonInstance {
		private static final Singleton INSTANCE = new Singleton(); 
	}
	//         ,    SingletonInstance.INSTANCE
	public static synchronized Singleton getInstance() {
		return SingletonInstance.INSTANCE;
	}
}
매 거
사실 매 거 진 을 사용 해도 단일 모델 을 실현 할 수 있 고 다 중 스 레 드 동기 화 문 제 를 피 할 수 있 을 뿐만 아니 라 반 직렬 화 를 방지 하여 새로운 대상 을 다시 만 들 수 있다.

enum Singleton {
	INSTANCE; //  
	public void say() {
		System.out.println("    ~");
	}
}
대응 테스트:

public static void main(String[] args) {
		Singleton instance1 = Singleton.INSTANCE;
		Singleton instance2 = Singleton.INSTANCE;
		System.out.println(instance1 == instance2);
		System.out.println(instance1.hashCode());
		System.out.println(instance2.hashCode());
		instance1.say();
	}
在这里插入图片描述
총결산
단일 모드 에서 사용 하 는 장면:
자주 만 들 고 소각 해 야 하 는 대상 이 대상 을 만 드 는 데 시간 이 너무 오래 걸 리 거나 자원 이 너무 많이 소모 되 거나(중량급 대상)자주 사용 하 는 대상,도구 류 대상,데이터 베이스 나 파일 을 자주 방문 하 는 대상(데이터 소스,session 공장)
이 글 은 여기까지 입 니 다.당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 실 수 있 기 를 바 랍 니 다!

좋은 웹페이지 즐겨찾기