国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

《CLR via C#》讀書筆記-線程同步(六)-C#中的單例模式

2019-11-06 06:24:47
字體:
來源:轉載
供稿:網友

        單例模式是經常用到的,最常用的情況就是創建一個數據庫連接。下面說一下C#的單例模式的實現方式

實現方式1

        最嚴謹的方式:

public sealed class Singleton{	//聲明一個私有鎖	PRivate static object m_lock = new object();		//單例變量的聲明	private static Singleton s_value=null;		//初始化的相關工作	//這兒需要注意,構造器的是私有的	private Singleton(){			}		//返回一個單例模式	public static Singleton GetSingleton(){		//		if(s_value!=null) return s_value;				//獲得私有鎖		Monitor.Enter(m_lock);		if(s_value==null){			//這兒的寫法是先聲明一個temp,然后通過InterLocked進行賦值			//目的就是保證,先完成“完整的”初始化后,再將對象引用賦給s_value			//防止出現如下的情況:CLR先分配完Singleton的內存,然后將引用賦值給s_value,最后再調用構造器			Singleton temp=new Singleton();			InterLocked.Exchange(s_value,temp);		}		Monitor.Exit(m_lock);				return s_value;	}	}        上面的代碼就是C#中最嚴謹的單例模式的代碼。C#可以“正確”的實現單例模式,但是java不能保證在任何地方都能正常工作。其原因就是:JVM在GetSingleton方法中第一次讀取時,將s_value讀入寄存器中。進行到第二個if語句時,直接從寄存器中讀取s_value的值。導致第二個if語句永遠都是true。因此會存在多個線程同時創建Singleton對象,因此在Java中有如此表現。

實現方式2

        第一種方式較為繁瑣,可直接利用CLR的一個特征:CLR保證類的構造器是線程安全的。因此可以使用粗暴的方式,如下:

public sealed class Singleton{		//單例變量的聲明	private static Singleton s_value=new Singleton();		//初始化的相關工作	//這兒需要注意,構造器的是私有的	private Singleton(){			}		//返回一個單例模式	public static Singleton GetSingleton(){ return s_value;}}        這種方式簡單粗暴。通過CLR的特征保證了線程安全,但是沒有保證單例。因此這種方式不能稱之為一個“單例模式”。因此對此方式進行修改

實現方式3

        根據方式2的修改,得到如下:

public sealed class Singleton{		//單例變量的聲明	private static Singleton s_value=new Singleton();		//初始化的相關工作	//這兒需要注意,構造器的是私有的	private Singleton(){			}		//返回一個單例模式	public static Singleton GetSingleton(){		if(s_value!=null) return s_value;				//這兒會有競爭,有可能多個線程都進行到這步,創建了多個Singleton對象		//但是通過調用CompareExchange方法,只有一個Singleton對象,將其賦予s_value		Singleton temp=new Singleton();		InterLocked.CompareExchange(s_value,temp,null);				return s_value;	}}        這兒也會存在一個小問題,就在Singleton temp=new Singleton();這句,多個線程可能會創建多個Singleton對象,但是通過CompareExchange方法,可以保證只有一個Singleton對象,其他的會被GC回收掉。優點就是快

4其他

        系統提供了一個System.Layz類,基本信息如下,其主要目的就是延遲初始化(延遲加載)

public class Lazy<T>{	public Lazy(Func<T> valueFactory,LazyThreadSafeMode mode);	public bool IsValueCreated{get;}	public T Value{get;}}       使用的例子如下:

public static void Main(){	//定義一個延遲加載變量	Lazy<string> sLazy = new Lazy<string>(()=>DateTime.Now.ToString(),LazyThreadSafeMode.PublicationOnly);		Console.WriteLine(sLazy.IsValueCreated);	Console.WriteLine(sLazy.Value);	Console.WriteLine(sLazy.IsValueCreated);	Thread.Sleep(1000);	Console.WriteLine(sLazy.Value);}        在構造器中還有一個參數:LazyThreadSafeMode,其定義如下:

        從上之下:ExecutionAndPublication使用了雙鎖技術;None線程不安全;PublicationOnly使用了CompareExchange技術。       

       另外還有一個延遲加載的靜態方法System.Threading.LazyInitializer方法


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宿松县| 琼中| 景谷| 博罗县| 卢湾区| 西城区| 永仁县| 东方市| 岚皋县| 威远县| 贵德县| 营口市| 修水县| 乐山市| 盘山县| 大兴区| 普兰县| 上思县| 高要市| 佛山市| 瑞安市| 陕西省| 大港区| 渑池县| 蒙自县| 阜城县| 光泽县| 洪江市| 会泽县| 汉阴县| 武冈市| 拜城县| 苗栗市| 子洲县| 含山县| 皮山县| 扬中市| 平罗县| 四川省| 乐至县| 徐汇区|