C\#단일 모델 을 실현 하 는 몇 가지 방법 총화
단일 모델 은 소프트웨어 공학 에서 가장 유명한 디자인 모델 중의 하나 이다.본질 적 으로 단일 모드 는 그 자체 에 의 해 한 번 만 예화 되 고 외부 에 이 인 스 턴 스 를 방문 하 는 인 터 페 이 스 를 제공 합 니 다.일반적으로 단일 대상 이 실례 화 를 진행 할 때 일반적으로 파 라미 터 를 가지 고 있 지 않다.왜냐하면 서로 다른 실례 화 요청 이 전달 하 는 파라미터 가 다 르 면 문제 가 발생 할 수 있 기 때문이다.(여러 요청 이 같은 매개 변수 로 전달 된다 면 공장 모델 은 더욱 고려 되 어야 한다)
C\#에서 단일 사례 를 실현 하 는 데 여러 가지 방법 이 있 는데 본 고 는 비 스 레 드 안전,완전 게으름뱅이 식,스 레 드 안전 과 저/고성능 집중 버 전 을 순서대로 소개 할 것 이다.
모든 실현 버 전에 서 다음 과 같은 몇 가지 공통점 이 있다.
4.567917.유일한,사유 적 이 고 인삼 이 없 는 구조 함수 로 외부 류 의 정례 화 를 허용 하지 않 습 니 다4.567917.류 는 밀봉 한 것 이다.비록 이것 은 강제 적 인 것 이 아니 지만 엄 밀 히 말 하면 상기 한 점 에서 볼 때 밀봉 류 는 JIT 의 최적화 에 도움 이 된다
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 Lazy
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.Lazy성능 VS 게으름뱅이 식
일반적으로 우 리 는 당신 의 구조 가 초기 화 되 어 시간 이 걸 리 는 일 을 수행 하지 않 는 한 완전히 게으름뱅이 식 을 실현 할 필요 가 없습니다.따라서 일반적으로 우 리 는 명시 적 인 정적 구조 함 수 를 사용 하면 적용 할 수 있다.
본 고 는 Implementing the Singleton Pattern in C\#에서 번역 되 었 고 작 가 는 글 에서 순환 테스트 를 했 으 며 구체 적 인 독 자 는 원문 을 직접 읽 을 수 있다.
Exception
구조 함수 초기 화 를 할 때 이상 을 던 질 수도 있 지만 전체 프로그램 에 치 명 적 이지 않 아야 하기 때문에 가능 한 경우 에 이런 이상 상황 을 스스로 처리 해 야 합 니 다.
총결산
위 에서 제공 한 몇 가지 실현 방법 중 일반적인 상황 에서 Version 4 를 사용 하 는 것 을 권장 하 며,때로는 단일 클래스 의 예화 보다 빠 를 때 다른 정적 구성원 을 인용 하지 않 는 다.이 경우 버 전 2 가 고려 되면 잠 금 을 넣 는 데 시간 이 걸 릴 것 처럼 보이 지만 실행 이 그렇게 느 리 지 않 습 니 다.문 제 는 쉽게 쓰 는 것 입 니 다.
분명히 버 전 1 은 영원히 고려 해 서 는 안 된다.버 전 3 은 버 전 5 와 비교 해서 도 고려 범위 안에 있 지 않다.
C\#단일 모드 구현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C\#단일 모드 구현 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.