C\#단일 모델 을 실현 하 는 몇 가지 방법 총화

6364 단어 c#단일 모드
소개 하 다.
단일 모델 은 소프트웨어 공학 에서 가장 유명한 디자인 모델 중의 하나 이다.본질 적 으로 단일 모드 는 그 자체 에 의 해 한 번 만 예화 되 고 외부 에 이 인 스 턴 스 를 방문 하 는 인 터 페 이 스 를 제공 합 니 다.일반적으로 단일 대상 이 실례 화 를 진행 할 때 일반적으로 파 라미 터 를 가지 고 있 지 않다.왜냐하면 서로 다른 실례 화 요청 이 전달 하 는 파라미터 가 다 르 면 문제 가 발생 할 수 있 기 때문이다.(여러 요청 이 같은 매개 변수 로 전달 된다 면 공장 모델 은 더욱 고려 되 어야 한다)
C\#에서 단일 사례 를 실현 하 는 데 여러 가지 방법 이 있 는데 본 고 는 비 스 레 드 안전,완전 게으름뱅이 식,스 레 드 안전 과 저/고성능 집중 버 전 을 순서대로 소개 할 것 이다.
모든 실현 버 전에 서 다음 과 같은 몇 가지 공통점 이 있다.
4.567917.유일한,사유 적 이 고 인삼 이 없 는 구조 함수 로 외부 류 의 정례 화 를 허용 하지 않 습 니 다4.567917.류 는 밀봉 한 것 이다.비록 이것 은 강제 적 인 것 이 아니 지만 엄 밀 히 말 하면 상기 한 점 에서 볼 때 밀봉 류 는 JIT 의 최적화 에 도움 이 된다
  • 정적 변 수 는 클래스 의 유일한 인 스 턴 스 를 가리 켜 야 합 니 다
  • 공공 정적 변 수 는 이러한 종류의 유일한 인 스 턴 스 를 얻 는 데 사 용 됩 니 다(필요 하 다 면 만들어 야 합 니 다)
  • 주의해 야 할 것 은 본 논문 의 모든 예 에서 하나의 Public static Instance 변 수 를 사용 하여 하나의 사례 를 방문 하 는 것 입 니 다.이 를 공공 함수 로 전환 하 는 것 은 쉽 지만 효율 과 스 레 드 안전 상의 향상 을 가 져 오지 않 습 니 다.
    Version 1-비 스 레 드 보안
    
    /// <summary>
    /// Bad code!Do not use! 
    /// </summary>
    public sealed class Singleton
    {
     private static Singleton instance = null;
     private Singleton() { }
     public static Singleton Instance
     {
      get
      {
       if (instance == null)
       {
        instance = new Singleton();
       }
       return instance;
      }
     }
    }
    이 버 전 은 다 중 스 레 드 에서 안전 하지 않 습 니 다.여러 개의 인 스 턴 스 를 만 들 것 입 니 다.생산 환경 에서 사용 하지 마 십시오!
    두 스 레 드 가 if(instance==null)판단 에 동시에 실 행 될 때 두 개의 인 스 턴 스 를 만 듭 니 다.이것 은 단일 모드 의 취지 에 어 긋 나 기 때 문 입 니 다.실제로 뒤의 그 스 레 드 에서 판단 하 는 것 은 이미 하나의 인 스 턴 스 가 생 성 되 었 지만 서로 다른 스 레 드 에 있어 서 스 레 드 간 의 통신 을 하지 않 으 면 그것 은 모른다.
    Version 2-간단 한 스 레 드 보안
    
    public sealed class Singleton2
    {
     private static Singleton2 instance = null;
     private static readonly object obj = new object();
     private Singleton2() { }
     public Singleton2 Instance
     {
      get
      {
       lock (obj)
       {
        if (instance == null)
        {
         instance = new Singleton2();
        }
        return instance;
       }
      }
     }
    }
    이 버 전 은 스 레 드 가 안전 합 니 다.스 레 드 가 공 유 된 대상 에 대한 잠 금 작업 을 통 해 같은 시간 에 하나의 스 레 드 만 lock{}의 코드 를 실행 할 수 있 도록 합 니 다.첫 번 째 스 레 드 가 intance 판단 이나 생 성 을 할 때 후속 스 레 드 는 이전 스 레 드 가 실 행 될 때 까지 기 다 려 야 하기 때문에 첫 번 째 스 레 드 만 intance 인 스 턴 스 를 만 들 수 있 도록 보장 합 니 다.
    그러나 불 행 히 도 인 스 턴 스 에 대한 요청 이 있 을 때마다 lock 작업 을 하기 때문에 성능 이 좋 지 않 습 니 다.
    주의해 야 할 것 은 private static object 변 수 를 사용 하여 잠 금 을 했 습 니 다.외부 클래스 에 접근 할 수 있 는 대상 을 잠 글 때 성능 이 저하 되 거나 잠 금 이 되 기 때 문 입 니 다.따라서 일반적으로 스 레 드 안전 을 위해 잠 금 을 넣 는 대상 은 private 여야 한다.
    Version 3-Double-check locking 의 스 레 드 보안
    
    /// <summary>
    /// Bad code ! Do not use!
    /// </summary>
    public sealed class Singleton3
    {
     private static Singleton3 instance = null;
     private static object obj = new object();
     private Singleton3() { }
     public static Singleton3 Instance
     {
      get
      {
       if (instance == null)
       {
        lock (obj)
        {
         if (instance == null)
         {
          instance = new Singleton3();
         }
        }
       }
       return instance;
      }
     }
    }
    이 버 전 은 방문 할 때마다 잠 금 작업 을 하지 않 고 스 레 드 안전 을 실현 하려 고 합 니 다.그 다음 에 이 코드 는 자바 에 작용 하지 않 습 니 다.자바 의 메모리 모델 은 구조 함수 가 반드시 다른 대상 이 인 스 턴 스 를 참조 하기 전에 완 성 될 것 이 라 고 보장 할 수 없습니다.그리고 중요 한 것 은 뒤의 실현 방식 보다 못 하 다 는 것 이다.
    Version 4-완전히 게으름뱅이 식 은 아니 지만 잠 그 지 않 은 스 레 드 는 안전 합 니 다.
    
    public sealed class Singleton4
    {
     private static readonly Singleton4 instance = new Singleton4();
     /// <summary>
     ///              C#                   
     /// </summary>
     static Singleton4() { }
     private Singleton4() { }
     public static Singleton4 Instance
     {
      get
      {
       return instance;
      }
     }
    }
    이 버 전 은 실현 은 매우 간단 하지만 스 레 드 는 안전 하 다.C\#의 정적 구조 함 수 는 클래스 의 인 스 턴 스 가 생 성 되 거나 정적 구성원 이 인 용 될 때 만 실 행 됩 니 다.전체 응용 프로그램 필드 에서 한 번 만 실 행 됩 니 다.현재 방식 을 사용 하 는 것 은 이전 버 전에 서 추가 적 인 판단 을 하 는 것 보다 훨씬 빠르다.
    물론 이 버 전에 도 약간의 흠 이 있다.
    진정한 의미 의 게으름뱅이 모드 가 아 닙 니 다.다음 버 전 실현 은 이 문 제 를 수정 할 것 이다.
    .NET 에서 만 beforefieldinit 특성,즉 게으름뱅이 식 실현 이 가능 합 니 다.또한.Net 1.1 이전 컴 파일 러 는 지원 되 지 않 았 지만 지금 은 문제 가 크 지 않 습 니 다.
    모든 버 전에 서 인 스 턴 스 를 readonly 로 설정 합 니 다.이것 은 코드 의 대학 뿐만 아니 라 매우 짧 아 보 입 니 다.
    Version 5-완전 게으름뱅이 정례 화
    
    public sealed class Singleton5
    {
     private Singleton5() { }
     public static Singleton5 Instance { get { return Nested.instance; } }
     private class Nested
     {
      //Explicit static constructor to tell C# compiler
      //not to mark type as beforefieldinit
      static Nested()
      {
      }
      internal static readonly Singleton5 instance = new Singleton5();
     }
    }
    이 버 전 은 다소 복잡 하고 이해 하기 어 려 울 것 같 지만,사실 이전 버 전의 하 자 를 문법 적 으로 실 현 했 을 뿐,인 스 턴 스 를 실제로 응용 할 때 만 실례 화 하 는 방식 을 내장 류 를 통 해 먼저 실현 했다.그 성능 표현 은 이전 버 전과 다름없다.
    Version 6-.NET 4 Lazytype 특성 사용
    
    public sealed class Singleton6
    {
     private static readonly Lazy<Singleton6> lazy =
       new Lazy<Singleton6>(()=> new Singleton6());
     public static Singleton6 Instance { get { return lazy.Value; } }
     private Singleton6() { }
    }
    .NET 4 또는 그 이상 버 전 을 사용한다 면 System.Lazytype 을 사용 하여 완전 게으름뱅이 식 을 실현 할 수 있 습 니 다.코드 도 깔끔 하고 성능 도 좋 습 니 다.
    성능 VS 게으름뱅이 식
    일반적으로 우 리 는 당신 의 구조 가 초기 화 되 어 시간 이 걸 리 는 일 을 수행 하지 않 는 한 완전히 게으름뱅이 식 을 실현 할 필요 가 없습니다.따라서 일반적으로 우 리 는 명시 적 인 정적 구조 함 수 를 사용 하면 적용 할 수 있다.
    본 고 는 Implementing the Singleton Pattern in C\#에서 번역 되 었 고 작 가 는 글 에서 순환 테스트 를 했 으 며 구체 적 인 독 자 는 원문 을 직접 읽 을 수 있다.
    Exception
    구조 함수 초기 화 를 할 때 이상 을 던 질 수도 있 지만 전체 프로그램 에 치 명 적 이지 않 아야 하기 때문에 가능 한 경우 에 이런 이상 상황 을 스스로 처리 해 야 합 니 다.
    총결산
    위 에서 제공 한 몇 가지 실현 방법 중 일반적인 상황 에서 Version 4 를 사용 하 는 것 을 권장 하 며,때로는 단일 클래스 의 예화 보다 빠 를 때 다른 정적 구성원 을 인용 하지 않 는 다.이 경우 버 전 2 가 고려 되면 잠 금 을 넣 는 데 시간 이 걸 릴 것 처럼 보이 지만 실행 이 그렇게 느 리 지 않 습 니 다.문 제 는 쉽게 쓰 는 것 입 니 다.
    분명히 버 전 1 은 영원히 고려 해 서 는 안 된다.버 전 3 은 버 전 5 와 비교 해서 도 고려 범위 안에 있 지 않다.
    C\#단일 모드 구현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C\#단일 모드 구현 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기