2015-01-15 1 views
4
난 항상 이런 식으로 구현 싱글을 참조

단축 :싱글 구현

public class Singleton 
{ 
    static readonly Singleton instance = new Singleton(); 
    public static Singleton Instance 
    { 
     get { return instance; } 
    } 

    protected Singleton() { } 
} 

을 :

public class Singleton 
{ 
    static Singleton instance; 
    static object obj = new object(); 

    public static Singleton Instance 
    { 
     get 
     { 
      lock (obj) 
      { 
       if (instance == null) 
       { 
        instance = new Singleton(); 
       } 
       return instance; 
      } 
     } 
    } 

    protected Singleton() { } 
} 

이처럼 구현에 문제가있을 수 있습니까? 첫 번째 구현에서와 마찬가지로 매우 초기에 게으른 초기화가 이루어 지므로 왜 이것이 인기있는 솔루션이 아닌지 궁금합니다. 이 잠금 상태가 필요 없습니다 및 필드가 컴파일러가

이의는 싱글 (안티) 패턴 자체에 대해 얘기하지 말자 몇 가지 최적화를 할 수있게된다 읽기 전용으로 표시되어 있으므로 그것은 빠르게도

하시기 바랍니다해야한다
+8

Jon Skeet [C#의 단일 패턴 구현] (http://csharpindepth.com/Articles/General/Singleton.aspx)을 읽고 "제 4 버전 - 게으른 것은 아니지만 잠금을 사용하지 않고 스레드로부터 안전 " – dcastro

+0

맛의 문제. 'Lazy '도 세 번째 패턴입니다. 첫 번째 예제는 잠금을 입력하기 전에 무효 * 확인도해야합니다. –

+2

그런 식으로 구현하는 데는 아무런 문제가 없습니다 (백킹 필드를'readonly'로 선언해야합니다). 그러나 속성에 액세스 할 때가 아니라 클래스의 정적 메서드가 호출 될 때 객체가 만들어지기 때문에 첫 번째 버전만큼 게으르지 않습니다. –

답변

7

그 (또는 다른 정적 인) 필드의 CLR will initialize the field upon the first use. 그것 promises to do so in a thread-safe manner.

코드의 차이점은 코드의 첫 번째 비트는 스레드 안전 지연 초기화를 지원하고 두 번째 코드는 스레드 안전하지 않은 지연 초기화를 지원한다는 것입니다. 즉, 코드가 Singleton.Instance의 첫 번째 코드에 액세스하지 않으면 new Singleton()이 생성되지 않습니다. 두 번째 클래스의 경우 Instance또는 (직접 또는 간접적으로) 다른 클래스의 정적 멤버에 액세스하는 즉시됩니다. 정적 생성자가 없기 때문에 더 균등하게 - may be initialized before that입니다. Lazy<T> 또한 promises thread-safety으로

public class Singleton 
{ 
    static readonly Lazy<Singleton> instance = 
     new Lazy<Singleton>(() => new Singleton()); 

    public static Singleton Instance 
    { 
     get { return instance.Value; } 
    } 

    static Singleton() { } 
    private Singleton() { } 
} 

: 당신이 크게 첫 번째 코드 블록을 단축 Lazy<T>를 사용할 수있는 .NET 4 있기 때문에 더 짧고 읽을 수있는 코드를 호의를

. 이렇게하면 new Singleton()은 한 번만 호출되며 실제로는 Singleton.Instance이 사용되는 경우에만 호출됩니다.

+1

생성자를 protected로 설정하면 클래스가 상속되어 싱글 톤이 아닌 클래스가 될 수 있습니다. –

+0

@Sriram 확실히, 그것은 또한 '사적인'일지도 모른다. :) – CodeCaster

관련 문제