程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#設計模式-單實例,

C#設計模式-單實例,

編輯:C#入門知識

C#設計模式-單實例,


單例模式就是保證在整個應用程序的生命周期中,在任何時刻,被指定的類只有一個實例,並為客戶程序提供一個獲取該實例的全局訪問點。

1.經典的模式

namespace singleClass
{
    class OnlyOneClass
    {
        private OnlyOneClass() { }
        private static OnlyOneClass instance;
        public static OnlyOneClass getInstance() {
            if (instance == null) {
                    instance = new OnlyOneClass();
                    return instance;
            }
            return instance;
        }
    }
}

分析一下:

1)通過私有化構造函數,使該類被調用的時候不能通過new來實現

2)定義一個靜態變量類,它的生命周期和程序的生命周期是一樣的,通過該靜態變量來保存該類的實例

2)通過一個靜態方法來實例化自己,並返還實例化後的結果,因為該方法先檢查全局的實例,再判斷是否再創建,保證只有一個實例

 

但是,這種方式如果碰到了多線程並發,問題就來了,如A,B兩個線程同時訪問了這個類,第一次檢查時候都是null,會出現兩個同時建立自己實例情況,這樣就違背單實例模式的原則

 

改進一下後:

2.俗稱懶漢模式

namespace singleClass
{
    class OnlyOneClass
    {
        private OnlyOneClass() { }
        public string thisname;
        private static OnlyOneClass instance;
        private static object _lock = new object();
        public static OnlyOneClass getInstance() {
            if (instance == null) {
                lock (_lock)
                {
                    if (instance == null)
                    {
                        instance = new OnlyOneClass();
                        return instance;
                    }
                }
            }
            return instance;
        }
    }
}

解析:

1)聲明一個object 變量,作為lock對象

2)先判斷instance的變量是否為null,如果不為null也就不用lock了,直接返回實例

3) 如果是null,鎖定對象,繼續判斷是否為null,以防有其他線程在lock前已經新建了實例,lock後可以保證在一個線程內操作

 

3.餓漢模式

class HungerClass{
        private HungerClass() { }
        private readonly static HungerClass instance=new HungerClass ();
        public static HungerClass getInstance(){
            return instance;
        }
    }
可以看出這種模式是在類初始化後就已經實例化了instance,不同於上面的懶漢模式時在調用getInstance()方法後實例化。
這種方式下,線程安全的問題將交給CLR。
 

4.測試

演示一下,通過聲明兩個OneClass類,只一個對其的thisname賦值,然後輸出這兩個類的thisname,看看另一個會怎樣
class Program
    {
        
        static void Main(string[] args)
        {
            Console.WriteLine("Get a instanc from OnlyOneClass!");
            try {
                OnlyOneClass one = OnlyOneClass.getInstance();//one 第一個類的變量
        
                Console.WriteLine(one.ToString());
                
                  while(true){
                      string ins = Console.ReadLine();
                      if (ins != "") { one.thisname = ins; }//只對one實例的thisname賦值
                      OnlyOneClass two = OnlyOneClass.getInstance();//two 第二個類的變量
                      Console.WriteLine(one.thisname +" one");//輸出 one實例的thisname
                      Console.WriteLine(two.thisname +" two"); //輸出 two實例的thisname
                      Thread.Sleep(1000);
                  }
            }
            catch (Exception e) {
                Console.WriteLine(e.Message);
            }
           
            Console.ReadKey();
        }
    }
}
可以看到這兩個實例都來自一個實例。
 
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved