C \ # 에서 Singleton 실현

4658 단어 Singleton
Singleton
Singleton 디자인 모델 의 다음 구현 은 Design Patterns: Elements of Reusable Object - Oriented Software [Gamma 95] 에서 설명 한 솔 루 션 을 사 용 했 으 나 속성 과 같은 C \ # 에서 사용 가능 한 언어 기능 을 이용 하여 수정 하 였 습 니 다.
using System;

public class Singleton

{

private static Singleton instance;

private Singleton() {}

public static Singleton Instance

{

get

{

if (instance == null)

{

instance = new Singleton();

}

return instance;

}

}

}


이 실현 은 주로 두 가지 장점 이 있다.

인 스 턴 스 는 인 스 턴 스 속성 방법 내부 에서 만 들 어 졌 기 때문에 클래스 는 추가 기능 (예 를 들 어 하위 클래스 를 예화) 을 사용 할 수 있 습 니 다. 원 하지 않 는 의존 도 를 도입 할 수 있 더 라 도.

대상 이 실례 를 만들어 달라 고 요구 할 때 까지 실례 화 를 실행 합 니 다.이런 방법 을 게 으 름 실례 화 라 고 한다.게 으 른 실례 화 는 프로그램 이 시 작 될 때 불필요 한 singleton 을 실례 화 하 는 것 을 피 할 수 있 습 니 다.
그러나 이런 실현 의 주요 단점 은 다 중 스 레 드 환경 에서 안전 하지 않다 는 것 이다.실행 과정의 서로 다른 스 레 드 가 인 스 턴 스 속성 방법 에 동시에 들 어가 면 여러 개의 Singleton 대상 인 스 턴 스 를 만 들 수 있 습 니 다.모든 스 레 드 는 다음 문 구 를 실행 하고 새로운 인 스 턴 스 를 만들어 야 합 니 다.
if (instance == null)


이 문 제 를 해결 하 는 방법 은 매우 많다.한 가지 방법 은 Double - Check Locking [Lea 99] 이 라 고 불 리 는 기술 을 사용 하 는 것 이다.C \ # 와 공공 언어 실행 라 이브 러 리 도 '정적 초기 화' 방법 을 제공 합 니 다. 이 방법 은 개발 자가 스 레 드 보안 코드 를 명시 적 으로 작성 하지 않 아 도 이 문 제 를 해결 할 수 있 습 니 다.
정적 초기 화
One of the reasons Design Patterns [Gamma 95] 가 정적 초기 화 를 피 하 는 이유 중 하 나 는 C + + 규범 이 정적 변수의 초기 화 순서 에 있어 다 의성 을 남 겼 기 때문이다.다행히도. NET Framework 는 그 변 수 를 통 해 초기 화 처리 방법 으로 이러한 다 의성 을 해결 했다.
public sealed class Singleton

{

private static readonly Singleton instance = new Singleton();

private Singleton(){}

public static Singleton Instance

{

get

{

return instance;

}

}

}


이 정책 에 서 는 클래스 의 모든 구성원 을 처음 참조 할 때 인 스 턴 스 를 만 듭 니 다.공용 언어 실행 라 이브 러 리 는 변 수 를 초기 화 하 는 것 을 책임 집 니 다.이 종 류 는 파생 을 막 기 위해 sealed 로 표시 되 어 있 으 며, 파생 은 인 스 턴 스 를 증가 시 킬 수 있 습 니 다.클래스 를 sealed 로 표시 하 는 장단 점 에 대한 토론 은 [Sells 03] 을 참조 하 시기 바 랍 니 다.또한 변 수 는 readonly 로 표 시 됩 니 다. 이 는 정적 초기 화 기간 (여기 표 시 된 예제) 이나 클래스 구조 함수 에서 만 변 수 를 할당 할 수 있 음 을 의미 합 니 다.
이 실현 은 앞의 예제 와 유사 하 며, 다른 점 은 공공 언어 실행 라 이브 러 리 에 의존 하여 변 수 를 초기 화 하 는 것 이다.싱글 톤 모드 에서 해결 하려 는 두 가지 기본 적 인 문 제 를 해결 할 수 있 습 니 다. 전역 접근 과 실례 화 제어 입 니 다.공공 정적 속성 은 방문 실례 에 전역 접근 점 을 제공 합 니 다.그 밖 에 구조 함 수 는 개인 적 인 것 이기 때문에 클래스 자체 이외 의 사례 로 Singleton 류 를 예화 할 수 없습니다.따라서 변 수 는 시스템 에 존재 할 수 있 는 유일한 인 스 턴 스 를 참조 합 니 다.
Singleton 인 스 턴 스 는 개인 정적 구성원 변수 에 의 해 참조 되 기 때문에 인 스 턴 스 속성 에 대한 호출 이 처음 인용 되 기 전에 예화 되 지 않 습 니 다.따라서 이 솔 루 션 은 Design Patterns 형식의 Singleton 과 마찬가지 로 게 으 름 실례 화 속성의 한 형식 을 실현 했다.
이런 방법의 유일한 잠재 적 인 단점 은 실례 화 메커니즘 에 대한 통제 권 이 비교적 적 다 는 것 이다.Design Patterns 형식 에서 실례 화 되 기 전에 기본 이 아 닌 구조 함 수 를 사용 하거나 다른 작업 을 수행 할 수 있 습 니 다.이 솔 루 션 은. NET Framework 에서 초기 화 를 수행 하기 때문에 이 옵션 이 없습니다.대부분의 경우 정적 초기 화 는. NET 에서 싱글 톤 을 실현 하 는 가장 좋 은 방법 이다.
다 중 스 레 드 싱글 톤
정적 초기 화 는 대부분의 상황 에 적합 합 니 다.프로그램 이 실례 화 를 지연 시 키 고 실례 화 되 기 전에 기본 이 아 닌 구조 함 수 를 사용 하거나 다른 작업 을 수행 해 야 하 며 다 중 루틴 환경 에서 작업 해 야 한다 면 다른 해결 방안 이 필요 합 니 다.그러나 일부 경우 '정적 초기 화' 예제 에서 처럼 공공 언어 런 타임 라 이브 러 리 에 의존 하여 스 레 드 의 안전성 을 확보 할 수 없습니다.이 경우 다 중 스 레 드 가 존재 하 는 상황 에서 대상 인 스 턴 스 만 만 만 들 수 있 도록 특정한 언어 기능 을 사용 해 야 합 니 다.더 흔히 볼 수 있 는 해결 방안 중 하 나 는 Double - Check Locking [Lea 99] 기술 을 사용 하여 서로 다른 스 레 드 를 막 고 singleton 의 새로운 인 스 턴 스 를 만 드 는 것 입 니 다.
메모: 공공 언어 라 이브 러 리 는 다른 환경 에서 흔히 볼 수 있 는 Double - Check Locking 사용 과 관련 된 문 제 를 해결 합 니 다.아래 의 실현 은 하나의 스 레 드 만 싱글 톤 인 스 턴 스 를 만 들 지 않 은 상태 에서 관건 적 인 구역 에 들 어 갈 수 있 습 니 다 (이 구역 은 lock 블록 으로 표 시 됩 니 다).
using System;

public sealed class Singleton

{

private static volatile Singleton instance;

private static object syncRoot = new Object();

private Singleton() {}

public static Singleton Instance

{

get

{

if (instance == null)

{

lock (syncRoot)

{

if (instance == null)

instance = new Singleton();

}

}

return instance;

}

}

}


이 방법 은 인 스 턴 스 가 필요 할 때 만 인 스 턴 스 를 만 들 수 있 도록 합 니 다.이 밖 에 변 수 는 volatile 로 설명 되 어 인 스 턴 스 변수 배분 이 완 료 된 후에 만 인 스 턴 스 변 수 를 방문 할 수 있 도록 합 니 다.마지막 으로 이 방법 은 잠 금 형식 자체 가 아 닌 syncRoot 인 스 턴 스 를 사용 하여 잠 금 을 합 니 다.
이 double - check locking 방법 은 스 레 드 병행 문 제 를 해결 하 는 동시에 모든 인 스 턴 스 속성 방법의 호출 에서 독점 잠 금 이 발생 하지 않도록 합 니 다.첫 방문 대상 에 대한 예화 지연 도 허용 합 니 다.실제로 응용 프로그램 은 이런 유형의 실현 을 필요 로 하지 않 는 다.대부분의 경우 정적 초기 화 방법 은 이미 충분 하 다.
C \ # 에서 Singleton 을 실현 하 는 것 은 다음 과 같은 장단 점 이 있 습 니 다.
장점.

. NET Framework 는 정적 변 수 를 초기 화 하 는 방법 과 언제 발생 하 는 지 명시 적 으로 지정 하기 때문에 정적 초기 화 방법 이 가능 합 니 다.

열 앞 에 있 는 '다 중 스 레 드 싱글 톤' 에서 설명 한 Double - Check Locking 기술 은 공공 언어 실행 라 이브 러 리 에서 올 바 르 게 구현 되 었 습 니 다.
결점.
다 중 스 레 드 프로그램 이 명시 적 초기 화 를 해 야 한다 면 스 레 드 문 제 를 피하 기 위해 조 치 를 취해 야 합 니 다.

좋은 웹페이지 즐겨찾기