using System;
using System.Collections.Generic;
/// <summary>
/// 適用於在多線程的情況下保證只有一個實例化對象的情況,例如銀行的操作系統
/// </summary>
namespace DoubleLockInstance
{
//----------------------------------
// 雙重鎖定單例
public sealed class Singleton
{
// 定義一個類對象,用於內部實現
private static Singleton myInstance;
// readonly - 這個成員只能在“類初始化”時賦值 ,所謂的類初始化,就是直接在類里面初始化
// 變量標記為 readonly,第一次引用類的成員時創建實例
private static readonly object lockRoot = new object ();
// 設置構造方法為私有,這樣就不能在外部實例化類對象了
private Singleton ()
{
}
// 實例化對象的方法
public static Singleton GetInstance ()
{
// 外部不能實例化對象,但是能調用類里面的靜態方法
// 外部需要調用這個方法來使用類對象,如果對象不存在就創建
// 這里面使用兩個判斷是否為null的原因是,我們不需要每次都對實例化的語句進行加鎖,只有當對象不存在的時候加鎖就可以了
if (myInstance == null) {
// 鎖定的作用就是為了保證當多線程同時執行這句代碼的時候保證對象的唯一性
// 鎖定會讓同時執行這段代碼的線程排隊執行
// lock里面需要用一個已經存在的對象來判斷,所以不能使用myInstance
lock (lockRoot) {
// 這里還需要一個判斷的原因是,如果多線程都通過了外層的判斷進行排隊
// 那將會實例化多個對象出來,所以這里還需要進行一次判斷,保證線程的安全
if (myInstance == null) {
myInstance = new Singleton ();
}
}
}
return myInstance;
}
}
}