생 성 모드 5 의 3 - singleton 단일 모드 의 8 가지 쓰기 비교

7630 단어 디자인 모드
단일 모드 의 8 가지 쓰기 비교
단일 모델 은 가장 자주 사용 하 는 디자인 모델 중 하나 로 디자인 모델 을 잘 아 는 친구 들 은 단일 모델 에 대해 낯 설 지 않다.일반적으로 단일 모델 을 소개 하 는 책 들 은 굶 주 린 한식 과 게 으 른 한식 이라는 두 가지 실현 방식 을 언급 한다.그러나 이 두 가지 방식 을 제외 하고 본 고 는 다른 몇 가지 사례 를 실현 하 는 방식 도 소개 할 것 이 니 우리 한번 봅 시다.
간단 한 소개
단일 모델 은 자주 사용 하 는 소프트웨어 디자인 모델 로 단일 대상 의 클래스 는 하나의 인 스 턴 스 만 존재 할 수 있다 고 정의 한다.
많은 경우 에 전체 시스템 은 하나의 전체적인 대상 만 가지 면 우리 가 시스템 전체의 행 위 를 조율 하 는 데 유리 하 다.예 를 들 어 특정한 서버 프로그램 에서 이 서버 의 설정 정 보 는 한 파일 에 저장 되 어 있 습 니 다. 이 설정 데 이 터 는 하나의 사례 대상 에서 통일 적 으로 읽 은 다음 에 서비스 프로 세 스 의 다른 대상 은 이 사례 대상 을 통 해 이 설정 정 보 를 얻 습 니 다.이런 방식 은 복잡 한 환경 에서 의 배치 관 리 를 간소화 했다.
기본 적 인 실현 사고.
단일 모드 요구 클래스 는 대상 에 게 하나의 인용 (영원히 같은 것) 과 이 인 스 턴 스 를 얻 는 방법 (정적 방법 이 어야 합 니 다. 보통 getInstance 라 는 이름 을 사용 합 니 다) 을 되 돌려 줄 수 있 습 니 다.
단일 사례 의 실현 은 주로 다음 과 같은 두 가지 절 차 를 통 해 이 루어 진다.
이러한 구조 방법 을 개인 적 인 방법 으로 정의 하면 다른 곳 의 코드 는 이러한 구조 방법 을 호출 하여 이러한 대상 을 예화 할 수 없고 이러한 정적 인 방법 으로 만 이러한 유형의 유일한 인 스 턴 스 를 얻 을 수 있다.이 클래스 에서 정적 인 방법 을 제공 합 니 다. 우리 가 이 방법 을 호출 할 때, 클래스 가 가지 고 있 는 인용 이 비어 있 지 않 으 면 이 인용 을 되 돌려 줍 니 다. 클래스 가 비어 있 으 면 이 종류의 실례 를 만 들 고, 실례 의 인용 을 클래스 가 유지 하 는 인용 에 부여 합 니 다.주의 사항
단일 모드 는 다 중 스 레 드 의 응용 장소 에서 반드시 조심해 서 사용 해 야 한다.만약 에 유일한 인 스 턴 스 가 생 성 되 지 않 았 을 때 두 개의 스 레 드 가 동시에 생 성 방법 을 호출 하면 그들 은 유일한 인 스 턴 스 의 존 재 를 감지 하지 못 하고 각자 인 스 턴 스 를 만 들 었 습 니 다. 그러면 두 개의 인 스 턴 스 가 구성 되 어 하나의 사례 모델 에서 유일한 원칙 을 위반 합 니 다.이 문 제 를 해결 하 는 방법 은 지시 류 가 이미 예화 되 었 는 지 의 변 수 를 위해 상호 배척 자 물 쇠 를 제공 하 는 것 이다.
단일 모드 의 8 가지 쓰기
1. 굶 주 린 사람 식 (정적 상수) [사용 가능]
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
/*       ,       */ 
private Singleton(){}

public static Singleton getInstance(){
    return INSTANCE;
}

} 장점: 이런 문법 은 비교적 간단 하 다. 바로 클래스 를 불 러 올 때 실례 화 를 완성 하 는 것 이다.스 레 드 동기 화 문 제 를 피 했다.
단점: 클래스 로 딩 할 때 실례 화 를 완성 하여 레이 지 로 딩 효과 에 미 치지 못 했 습 니 다.만약 처음부터 끝까지 이 인 스 턴 스 를 사용 한 적 이 없다 면 메모리 의 낭 비 를 초래 할 것 이다.
2. 굶 주 린 사람 식 (정적 코드 블록) [사용 가능]
public class Singleton {
private static Singleton instance;

static {
    instance = new Singleton();
}
/*       ,       */ 
private Singleton() {}

public Singleton getInstance() {
    return instance;
}

} 이러한 방식 은 위의 방식 과 유사 합 니 다. 클래스 를 예화 하 는 과정 을 정적 코드 블록 에 두 었 을 뿐 이 고 클래스 를 불 러 올 때 정적 코드 블록 에 있 는 코드 를 실행 하여 클래스 의 인 스 턴 스 를 초기 화 합 니 다.장단 점 은 위 와 같다.
3. 게으름뱅이 식 (라인 이 안전 하지 않 음) [사용 불가]
public class Singleton {
private static Singleton singleton;
/*       ,       */ 
private Singleton() {}

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

} 이 표기 법 은 레이 지 로 딩 의 효 과 를 냈 으 나 단선 에서 만 사용 할 수 있 습 니 다.만약 에 다 중 스 레 드 에서 한 스 레 드 가 if (singleton = null) 판단 문 블록 에 들 어가 면 미래 에 아래로 실행 해 야 하고 다른 스 레 드 도 이 판단 문 구 를 통과 하면 여러 개의 인 스 턴 스 가 생 길 것 이다.그래서 다 중 스 레 드 환경 에서 이런 방식 을 사용 할 수 없습니다.
4. 게으름뱅이 식 (스 레 드 안전, 동기 화 방법) [추천 하지 않 음]
public class Singleton {
private static Singleton singleton;
/*       ,       */ 
private Singleton() {}

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

} 위의 세 번 째 실현 방식 의 스 레 드 가 안전 하지 않 은 문 제 를 해결 하고 스 레 드 를 동기 화하 면 됩 니 다. 그래서 getInstance () 방법 에 대해 스 레 드 를 동기 화 했 습 니 다.
단점: 효율 이 너무 낮 습 니 다. 모든 스 레 드 는 클래스 의 인 스 턴 스 를 얻 으 려 면 getInstance () 방법 을 동기 화 해 야 합 니 다.사실 이 방법 은 실례 화 코드 를 한 번 만 실행 하면 충분 하 다. 뒤에 있 는 것 은 이런 실례 를 얻 으 려 면 바로 return 하면 된다.방법 은 동기 화 효율 이 너무 낮 아서 개선 해 야 한다.
5. 게으름뱅이 식 (스 레 드 안전, 동기 코드 블록) [사용 불가]
public class Singleton {
private static Singleton singleton;
/*       ,       */ 
private Singleton() {}

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

} 네 번 째 실현 방식 은 동기 화 효율 이 너무 낮 기 때문에 동기 화 방법 을 버 리 고 동기 화 된 코드 블록 으로 바 꿉 니 다.그러나 이런 동기 화 는 스 레 드 동기 화 작용 을 하지 못 한다.세 번 째 실현 방식 이 만 나 는 상황 과 일치 합 니 다. 만약 에 하나의 스 레 드 가 if (singleton = null) 판단 문 블록 에 들 어가 면 미래 에 아래로 실행 해 야 합 니 다. 다른 스 레 드 도 이 판단 문 구 를 통과 하면 여러 개의 인 스 턴 스 가 생 길 수 있 습 니 다.
6. 이중 검사 [추천 용]
public class Singleton {

    private static volatile Singleton singleton;
    /*       ,       */ 
    private Singleton() {}

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

Double - Check 개념 은 다 중 스 레 드 개발 자 에 게 낯 설 지 않 습 니 다. 코드 에서 보 듯 이 우 리 는 if (singleton = = null) 검 사 를 두 번 했 습 니 다. 그러면 스 레 드 안전 을 보장 할 수 있 습 니 다.이렇게 하면 실례 화 코드 는 한 번 만 실행 하고 나중에 다시 방문 할 때 if (singleton = = null) 를 판단 하여 직접 return 실례 화 대상 을 판단 합 니 다.
장점: 스 레 드 안전;로드 지연;효율 이 비교적 높다.
7. 정적 내부 클래스 [추천 용]
public class Singleton {
    /*       ,       */ 
    private Singleton() {}

    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

이런 방식 은 굶 주 린 한식 방식 이 채택 한 메커니즘 과 유사 하지만 또 다르다.둘 다 클래스 로 딩 메커니즘 을 사용 하여 인 스 턴 스 를 초기 화 할 때 하나의 스 레 드 만 있 도록 합 니 다.서로 다른 곳 에서 굶 주 림 식 방식 은 싱글 턴 류 가 불 러 오 면 예화 되 고 Lazy - Loading 의 역할 이 없 으 며 정적 내부 방식 은 싱글 턴 류 가 불 러 올 때 바로 예화 되 지 않 고 예화 가 필요 할 때 getInstance 방법 을 사용 해 싱글 턴 인 스 턴 스 류 를 불 러 와 싱글 턴 의 예화 가 이 루어 진다.
클래스 의 정적 속성 은 클래스 를 처음 불 러 올 때 만 초기 화 되 기 때문에 JVM 은 스 레 드 의 안전성 을 확보 하 는 데 도움 을 주 었 습 니 다. 클래스 를 초기 화 할 때 다른 스 레 드 는 들 어 갈 수 없습니다.
장점: 스 레 드 가 안전 하지 않 고 로드 지연, 효율 이 높 습 니 다.
8. 매 거 [추천 용]
public enum Singleton { INSTANCE; public void whateverMethod() {
}

} JDK 1.5 에 추 가 된 매 거 진 을 통 해 단일 모드 를 구현 합 니 다. 다 중 스 레 드 동기 화 문 제 를 피 할 수 있 을 뿐만 아니 라 새로운 대상 을 다시 만 드 는 것 도 방지 할 수 있 습 니 다. JDK 1.5 에 매 거 진 것 이 추가 되 었 기 때문에 실제 프로젝트 개발 에 서 는 이렇게 쓰 는 사람 이 드 물 었 습 니 다.
장점.
시스템 메모리 에 이 종 류 는 하나의 대상 만 존재 하고 시스템 자원 을 절약 하 며 자주 소각 해 야 하 는 대상 에 대해 단일 모드 를 사용 하면 시스템 성능 을 향상 시 킬 수 있 습 니 다.
결점.
하나의 사례 류 를 예화 하려 면 new 를 사용 하 는 것 이 아니 라 해당 대상 을 얻 는 방법 을 사용 하 는 것 을 기억 해 야 한다. 특히 소스 코드 가 보이 지 않 을 때.
적용 장소
자주 만 들 고 소각 해 야 하 는 대상, 대상 을 만 드 는 데 시간 이 너무 오래 걸 리 거나 자원 이 너무 많이 소모 되 지만 자주 사용 하 는 대상, 도구 류 대상, 데이터 베이스 나 파일 의 대상 을 자주 방문 해 야 합 니 다.

좋은 웹페이지 즐겨찾기