디자인 모델 [1] - 단일 모델 은 도대체 몇 가지 표기 법 입 니까?

8982 단어 디자인 모드
[TOC]
단일 모드 는 비교적 간단 한 디자인 모델 이자 창설 형 모드 (창설 대상 을 제공 하 는 모드 나 방식) 에 속한다.요점:
  • 1. 하나의 클래스 와 관련 되 어 있 습 니 다. 이 클래스 는 자신의 대상 을 만 듭 니 다. (다른 곳 에서 만 드 는 방법 을 다시 쓸 수 없습니다. 클래스 를 초기 화 할 때 만 들 거나 개인 적 인 방법 을 제공 하여 방문 하거나 만 들 수 있 습 니 다. 하나의 대상 만 생 성 되 는 것 을 확보 해 야 합 니 다)
  • 2. 단일 모델 이 반드시 스 레 드 가 안전 하지 않 은 것 은 아니다.

  • 3. 단일 모드 는 두 가지 로 나 눌 수 있 습 니 다. 게으름뱅이 모드 (처음 클래스 를 사용 할 때 만 만 만 들 수 있 습 니 다. 클래스 로 딩 할 때 너무 게 으 르 고 사용 할 때 만 얻 을 수 있 습 니 다. 없 으 면 만 들 수 있 습 니 다. 단일 모드 이기 때문에 처음 사용 할 때 만 없 으 며 만 든 후에 같은 대상 을 계속 사용 할 수 있 습 니 다), 굶 주 린 남자 모드(클래스 로 딩 할 때 이미 생 성 되 었 습 니 다. 굶 주 린 사람 이 배 고 파 서 갈증 이 나 는 것 으로 이해 할 수 있 습 니 다. 반드시 자원 을 자신의 손 에 꼭 잡 아 당 겨 야 하기 때문에 클래스 로 딩 할 때 먼저 인 스 턴 스 를 만 듭 니 다)
    키워드:
  • 단 례: singleton
  • 실례: instance
  • 동기 화: synchronized

  • 굶 주 린 남자 모델
    1. 사유 속성
    첫 번 째 singlepublic 유형 명 으로 직접 방문 할 수 있다.
     public class Singleton {
        //        ,                  
        private Singleton(){
        }
        //    public,        Singleton.instance   
        static Singleton instance = new Singleton();
    }

    2. 공유 속성
    두 번 째 는 Singleton 수식 private 으로 접근 하려 면 singleton 방법 을 제공 해 야 한다.
    public class Singleton {
        private Singleton(){
        }
        //   private  ,       get       
        private static Singleton instance = new Singleton();
        // static       ,         
        public static Singleton getInstance(){
            return instance;.
        }
    }

    3. 게 으 름 피 우기
    굶 주 린 모드, 이러한 표기 법 은 문제 가 없습니다. 스 레 드 보안 문제 (클래스 static 멤버 가 만 들 때 기본적으로 잠 겨 있 고 여러 스 레 드 에 동시에 가 져 오지 않 습 니 다) 가 없 지만 단점 이 있 습 니 다. static 의 초기 화 는 클래스 로 딩 할 때 진행 되 기 때문에 클래스 로 딩 은 instance 입 니 다.이 를 실현 하려 면 초기 화 를 일찍 하 는 것 이 좋 은 점 은 나중에 직접 사용 할 수 있다 는 것 이다. 나 쁜 점 은 자원 을 낭비 하 는 것 이다. 만약 개별 유형 만 이런 방법 을 사용한다 면 의존 하 는 데 이 터 량 이 비교적 적 으 면 이런 방법 도 비교적 좋 은 단일 방법 이다. 단일 모델 에 서 는 일반적으로 호출 ClassLoader 이다.방법 으로 클래스 마 운 트 를 촉발 합 니 다. 상기 두 가지 굶 주 린 모델 은 분명히 실현 되 지 않 았 습 니 다 getInstance() (개인 적 으로 사용 할 때 만 클래스 마 운 트 를 촉발 합 니 다). 그래서 아래 에 굶 주 린 모델 의 개선 판 이 있 습 니 다. 내부 클래스 를 이용 하여 게 으 름 마 운 트 를 실현 합 니 다. 이런 방식 lazyload 이 로드 되 었 습 니 다. 그러나 Singleton 도 반드시 초기 화 되 는 것 은 아 닙 니 다. instance 까지 기 다 려 야 합 니 다.주동 적 으로 사 용 될 때, 즉 현식 호출 SingletonHolder 방법 을 사용 할 때 만 현식 적재 getInstance() 클래스 를 실례 화 SingletonHolder 할 수 있다. 이런 방법 은 클래스 적재 기 를 사용 하여 하나의 라인 만 초기 화 instance 할 수 있 음 을 보증한다. 그러면 단일 사례 를 보증 하고 게 으 름 부 하 를 실현 할 수 있다.
    주의해 야 할 것 은 정적 내부 류 는 단일 사례 가 다 중 스 레 드 에서 보 내 는 스 레 드 안전성 을 확보 하지만 직렬 화 대상 을 만 났 을 때 기본 적 인 방식 으로 실 행 된 결 과 는 여러 가지 입 니 다.
    public class Singleton {
        private Singleton(){
        }
        //   
        private static class SingletonHolder{
            private static final Singleton instance = new Singleton();
        }
        //               
        public static final Singleton getInstance(){
            return SingletonHolder.instance;
        }
    }

    게으름뱅이 모드
    가장 기본 적 인 코드 (라인 이 안전 하지 않 음):
    public class Singleton {
        private static Singleton instance = null;
        private Singleton(){
        }
        public static Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

    이러한 표기 법 은 인 스 턴 스 instance 를 가 져 올 때마다 판단 합 니 다. 그렇지 않 으 면 instance 하나 가 나 옵 니 다. 그렇지 않 으 면 이전에 존 재 했 던 new 으로 바로 돌아 갑 니 다. 그러나 이러한 표기 법 은 스 레 드 가 안전 하지 않 습 니 다. 여러 스 레 드 가 있 을 때 instance방법 은 null 과 같은 지 여 부 를 판단 할 때 각각 새로운 인 스 턴 스 를 만 듭 니 다. 그러면 하나의 예 를 보장 할 수 없습니다. 그래서 우 리 는 동기 화 자 물 쇠 를 생각 합 니 다. synchronized 키 워드 를 사용 합 니 다. 동기 화 자 물 쇠 를 추가 하 는 코드 (스 레 드 가 안전 하고 효율 이 높 지 않 습 니 다)
    public class Singleton {
       private static Singleton instance = null;
       private Singleton() {}
       public static Singleton getInstance() {
           synchronized(Singleton.class){
         if (instance == null)
           instance = new Singleton();
       }
       return instance;
       }
    }

    이렇게 되면 getInstance() 방법 이 잠 겨 있 습 니 다. 두 개의 스 레 드 가 동시에 이 방법 에 접근 할 때 한 스 레 드 가 먼저 동기 화 자 물 쇠 를 얻 게 됩 니 다. 그러면 이 스 레 드 는 실 행 될 수 있 고 다른 스 레 드 는 기 다 려 야 합 니 다. 첫 번 째 스 레 드 가 실 행 될 때 까지 기 다 려 야 합 니 다 getInstance()방법 후에 야 실행 할 수 있 습 니 다. 이 코드 는 스 레 드 가 안전 하지만 효율 이 높 지 않 습 니 다. 만약 에 스 레 드 가 많 으 면 모든 스 레 드 를 기다 리 게 해 야 합 니 다. 그러면 효율 이 크게 떨 어 집 니 다. 그러면 우 리 는 자 물 쇠 를 기다 리 는 확률 을 다시 낮 추 는 것 이 바로 우리 가 말 하 는 이중 검사 자물쇠 (쌍 검사 자물쇠) 입 니 다.
    public class Singleton {
       private static Singleton instance = null;
       private Singleton() {}
       public static Singleton getInstance() {
       if (instance == null){
         synchronized(Singleton.class){
           if (instance == null)
             instance = new Singleton();
         }
       }
       return instance;
       }
    }

    1. 첫 번 째 if 판단 은 자물쇠 의 출현 확률 을 낮 추기 위해 서 입 니 다. 앞의 코드 는 같은 방법 을 실행 하면 자 물 쇠 를 촉발 합 니 다. 여 기 는 getInstance() 밖 에 없습니다.비어 있 을 때 만 터치 합 니 다. 첫 번 째 로 들 어 가 는 스 레 드 는 대상 을 만 듭 니 다. 다른 스 레 드 가 다시 들 어 갈 때 대상 이 생 성 되 지 않 습 니 다. 전체 방법 이 동기 화 되면 모든 스 레 드 가 줄 을 서 야 효율 이 떨 어 집 니 다. 2. 두 번 째 if 판단 은 이전 코드 와 같은 역할 을 합 니 다.
    위의 코드 는 이미 문제 가 없 는 것 처럼 보이 지만 사실은 아주 작은 확률 로 문제 가 발생 할 수 있다. 그러면 우 리 는 먼저 원자 조작, 명령 재배 치 를 알 아 보 자.
    1. 원자 조작
  • 원자 조작 은 분리 할 수 없 는 조작 으로 이해 할 수 있다. 즉, 여러 조작 으로 나 누 어 진행 할 수 없 을 정도 로 작 았 다 는 것 이다. 그러면 컴퓨터 에서 완전히 실행 되 었 거나 전혀 실행 되 지 않 았 거나 중간 상태 로 실행 되 지 않 았 으 며 중간 상태 로 이해 할 수 있다. 예 를 들 어 할당 문 구 는 원자 조작 이다.
  •  n = 1; //         

    n 의 값 이 이전에 0 이 었 다 고 가정 하면 이 작업 의 배후 에는 성공 n 이 1 과 같 거나 성공 n 이 0 과 같 지 않 으 면 중간 상태 가 존재 하지 않 습 니 다. 병발 하 는 과정 에서 도 마찬가지 입 니 다. 다음은 원자 조작 이 아 닌 코드 입 니 다.
    int n =1;  //      

    원인: 이 문 구 는 두 가지 조작 으로 나 눌 수 있 습 니 다. 1. 성명 변수 n, 2. 변 수 를 1 로 할당 합 니 다. 그 중에서 우 리 는 n 이 성명 되 었 으 나 미 처 할당 하지 못 한 상태 임 을 알 수 있 습 니 다. 이러한 상황 은 병발 과정 에서 여러 스 레 드 가 n 을 동시에 사용 하면 불안정 한 결 과 를 초래 할 수 있 습 니 다.
    2. 다시 정렬 명령
    명령 정렬 이란 컴퓨터 가 우리 코드 를 최적화 시 키 고 최적화 하 는 과정 에서 마지막 결과 에 영향 을 주지 않 는 전제 에서 원자 작업 의 순 서 를 조정 하 는 것 이다. 예 를 들 어 아래 의 코드:
    int a ;   //   1 
    a = 1 ;   //   2
    int b = 2 ;     //   3
    int c = a + b ; //   4

    정상 적 인 상황 에서 집행 순 서 는 1234 이 어야 하지만 실제 적 으로 3124 또는 1324 일 수 있 습 니 다. 이것 은 문장 3 과 4 에 원자 문제 가 없 기 때문에 원자 조작 으로 나 누 어 다시 배열 할 수 있 습 니 다. 원자 조작 과 명령 재 배열 의 기본 적 인 이 해 를 통 해 우리 의 코드 를 볼 수 있 습 니 다.
    주로singleton 우리 가 말 한 바 에 따 르 면 이 문 구 는 원자 조작 이 아니 라 분 리 됩 니 다. 사실은 JVM (자바 가상 머 신) 이 이 문 구 를 조작 합 니 다.
  • 1. 인 스 턴 스에 메모리 할당
  • 2. Singleton 의 구조 함 수 를 호출 하여 한 구성원 변 수 를 초기 화하 고 인 스 턴 스 를 생 성하 여 다른 메모리 공간 에 두 었 습 니 다
  • 3. 인 스 턴 스 대상 을 분 배 된 메모리 공간 으로 가리 키 고 이 단 계 를 실행 해 야 실제 완 료 됩 니 다. 인 스 턴 스 는 null 이 아 닙 니 다.
  • 한 라인 안에 문제 가 없다 면 여러 라인 에서 JVM 이 지령 재배 열의 최 적 화 를 하면 문제 가 생 길 수 있다. 왜냐하면 두 번 째 단계 와 세 번 째 단계 의 순 서 는 보장 할 수 없 기 때문이다. 최종 실행 순 서 는 1 - 2 - 3 일 수도 있 고 1 - 3 - 2 일 수도 있다. 후자 라면 3 실행 이 끝나 고 2 가 실행 되 지 않 기 전에 라인 2 에 점령 당 한다. 이때 instance = new Singleton()이미 instance 입 니 다.이미 null 이 아 닙 니 다. 그리고 그 가 직접 가 져 와 서 사용 하면 오류 가 발생 합 니 다. 이 문제 에 대해 우리 가 사용 하 는 방안 은 instance 키 워드 를 더 하 는 것 입 니 다.
    public class Singleton {
       private static volatile Singleton instance = null;
       private Singleton() {}
       public static Singleton getInstance() {
       if (instance == null){
         synchronized(Singleton.class){
           if (instance == null)
             instance = new Singleton();
         }
       }
       return instance;
       }
    }
    instance==null 의 역할: 명령 을 다시 배열 하 는 것 을 금지 하고 instancenull 로 설명 한 후에 할당 이 완료 되 기 전에 읽 기 동작 을 호출 하지 않 습 니 다. 즉, 한 스 레 드 가 완전히 완성 되 지 않 았 을 때 volatile 다른 스 레 드 는 읽 기 동작 을 사용 할 수 없습니다.
  • 위의 방법 으로 단일 사례 를 실현 하 는 것 은 모두 복잡 한 직렬 화 와 반사 가 없 을 때 를 바탕 으로 하 는 것 이다. 그렇지 않 으 면 문제 가 있 을 수 있다. 그리고 마지막 방법 은 매 거 진 것 으로 단일 사례 를 실현 하 는 것 이다. 이것 은 비교적 이상 적 인 단일 모델 로 서열 화 체 제 를 자동 으로 지원 하고 여러 번 의 사례 화 를 절대적 으로 방지 하 는 것 이다.
  • public enum Singleton {
        INSTANCE;
        public void doSomething() {
    
        }
    }

    이상 에서 매 거 방식 을 가장 추천 합 니 다. 물론 현재 컴퓨터 의 자원 은 비교적 충분 합 니 다. 굶 주 린 사람 방식 도 좋 습 니 다. 그 중에서 게으름뱅이 모델 에서 다 중 스 레 드 문제 와 관련 되면 쓰기 도 주의해 야 합 니 다.
    마지막 으로 volatile 키 워드 는 명령 의 정렬 만 금지 하고 가시 성 을 확보 합 니 다. (한 스 레 드 가 변 수 를 수정 하여 다른 스 레 드 에 있어 서 는 즉시 볼 수 있 습 니 다. 메 인 메모리 에 즉시 동기 화 되 기 때 문 입 니 다) 그러나 원자 성 을 보장 하지 않 습 니 다.
    [작가 소개]: 진 회, 공중 번호 [진 회 잡화점] 작가, 기술 의 길 은 한 때 가 아니 라 산 이 높 고 물이 길 어서 천천히 달 려 도 멈 추 지 않 습 니 다. 이 세 계 는 모든 것 이 빠 르 고 빠 르 기 를 바 랍 니 다. 하지만 저 는 모든 걸음 을 잘 걷 고 모든 글 을 잘 써 서 여러분 과 함께 교류 하 기 를 바 랍 니 다.
    이 글 은 단지 자신 (본 초보) 을 대표 하여 기록 을 쌓 거나 필 기 를 배 웁 니 다. 권리 침해 가 있 으 면 작가 에 게 연락 하여 확인 하고 삭제 하 십시오. 사람 은 완벽 한 사람 이 없고 글 도 마찬가지 입 니 다. 문필 이 여 리 고 재능 이 없 으 니 뿌리 지 마 세 요. 잘못된 점 이 있 으 면 지적 해 주 십시오. 감사 하기 그 지 없습니다.

    좋은 웹페이지 즐겨찾기