單例模式的幾種方法

單例模式

1.很差的解法(只適用於單例模式)

把構造函數設爲私有函數以禁止他人建立。定義一個靜態實例,在須要的時候建立該實例。c#

 1 public sealed class Singleton1
 2 {
 3     //私有方法建立Singleton1
 4     private Singleton1(){
 5     }
 6     
 7     private static Singleton1 instance = null;
 8     public static Singleton1 Instance
 9     {
10         get{
11             if(instance == null)
12                 instance = new Singleton1();
13                 
14             return instance;
15         }
16     }
17 }

 

只適合單線程,若是多線程同時運行到判斷語句,會建立多個實例。多線程

2.很差的解法(適應多線程,低效率)

對第一種方法的改進,能夠經過添加一個同步鎖。函數

public sealed class Singleton2
{
    //私有方法建立Singleton2
    private Singleton2(){
    }
    
    private static readonly object syncObj = new object();
    
    private static Singleton2 instance = null;
    public static Singleton2 Instance
    {
        get{
        lock(syncObj){
            if(instance == null)
                instance = new Singleton2();
                }  
            return instance;
        }
    }
}

 

此時只有一個線程能夠獲得同步鎖。其餘的線程只能等待,等第一個線程執行完建立實例或獲得實例後,其餘線程再依次進行得到同步鎖和判斷。spa

3.可行解法 加鎖先後兩次判斷實例

第二種方法在每次線程都會執行同步鎖,而同步鎖是一個效率很低費時間的操做,因此要避免加鎖操做。
咱們在實例尚未建立前須要加鎖,以後就不須要加鎖操做了,進一步改進以下:線程

public sealed class Singleton3
{
    //私有方法建立Singleton3
    private Singleton3(){
    }
    
    private static readonly object syncObj = new object();
    
    private static Singleton3 instance = null;
    public static Singleton3 Instance
    {
        get
        {
            if(instance == null)
            {
                lock(syncObj){
                    if(instance == null)
                        instance = new Singleton3();
                    }
               return instance;
            }
        }
    }
}


4.推薦解法 利用靜態構造函數

在c#中,靜態構造函數只會被調用一次。能夠利用這一特性進行單例模式。code

public sealed class Singleton4
{
    private Singleton4(){
    }
    
    private static Singleton4 instance = new Singleton4();
    public static Singleton4 Instance
    {
        get{
            return instance;
        }
    }
}

 

5. 按需建立實例

public sealed class Singleton5
{
    Singleton5(){
    }
    
    public static Singleton5 Instance{
        get{
            return Nested.instance;
        }
    }
    
    class Nested
    {
        static Nested(){
        }
        internal static readonly Singleton5 instance = new Singleton5();
    }
}
相關文章
相關標籤/搜索