日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式学习笔记十:单例模式(Singleton Pattern)

發(fā)布時間:2024/10/8 asp.net 100 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式学习笔记十:单例模式(Singleton Pattern) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

????1.概述
????單例模式(Singleton Pattern)又稱單件模式,單例模式保證一個類僅有一個實例,并提供一個訪問的他的全局訪問點。通常我們可以讓一個全局變量使得一個對象被訪問,但它不能防止你實例化對個對象,一個最好的辦法就是,讓類自身負(fù)責(zé)保存他的唯一實例,這個類可以保證沒有其他實例可以被創(chuàng)建并且他可以提供一個訪問該實例的方法。
????使用場合:當(dāng)類只能有一個實例存在,并且可以在全局訪問時,這個唯一的實例應(yīng)該可以通過子類實現(xiàn)擴(kuò)展,并且用戶無須更改代碼即可使用。前面學(xué)習(xí)過得工廠類經(jīng)常被實例化為全局唯一的單件,可能的單件還有系統(tǒng)的管理日志的對象、關(guān)鍵字生成對象和外部設(shè)備接口對象等。
????結(jié)構(gòu):

????代碼:
Singleton
????public?class?Singleton
????
{
????????
private?static?Singleton?instance;
????????
private?static?readonly?object?syncRoot?=?new?object();
????????
private?Singleton()
????????
{
????????}

????????
public?static?Singleton?GetInstance()
????????
{
????????????
if?(instance?==?null)
????????????
{
????????????????instance?
=?new?Singleton();
????????????}

????????????
return?instance;
????????}

????}

????單例模式提供了全局唯一的訪問入口,易于控制可能發(fā)生的沖突。
????單例模式因為Singleton類封裝它的唯一實例,這樣他可以嚴(yán)格的控制客戶怎樣訪問它以及何時訪問他。
????單例模式是對靜態(tài)方法的一種改進(jìn),首先避免了全局變量對系統(tǒng)的污染,其次他可以有子類,可以定義虛方法,具有多態(tài)性。而類中的靜態(tài)方法是不能被定義為虛方法,因此不具有多態(tài)性。
????2.實例
????1.單件計數(shù)器
????最簡單的單例模式應(yīng)用就是計數(shù)器,在基于Web的應(yīng)用中,我們希望有一個全局計數(shù)器來統(tǒng)計單件的次數(shù),為此我們要定義一個單件計數(shù)器:
Counter
????/**////?<summary>
????
///?計數(shù)器
????
///?</summary>

????public?class?Counter
????
{
????????
private?int?intCounter?=?0;
????????
private?static?Counter?MyCounter;
????????
public?int?Count()
????????
{
????????????intCounter?
=?intCounter?+?1;
????????????
return?intCounter;
????????}

????????
public?static?Counter?GetInstance()
????????
{
????????????
if?(MyCounter?==?null)
????????????
{
????????????????MyCounter?
=?new?Counter();
????????????}

????????????
return?MyCounter;
????????}

????}

????調(diào)用代碼:
????????????for?(int?i?=?0;?i?<?10;?i++)
????????????
{
????????????????Console.WriteLine(Counter.GetInstance().Count());
????????????}
????2.多線程時的單例以及雙重鎖定
????在多線程程序中,多個線程同時訪問Singleton類時,調(diào)用GetInstance()方法,會有可能造成創(chuàng)建多個實例,我們可以給進(jìn)程加一把鎖來處理。鎖(Lock)是確保當(dāng)一個線程位于代碼的臨界區(qū)時,另一個線程不能進(jìn)入該臨界區(qū),如果其他線程試圖進(jìn)入鎖定的代碼,則他將一直等待(即被阻止),直到該對象被釋放【MSDN】。?
????下面來看加鎖的單例模式:
Singleton
????public?class?Singleton
????
{
????????
private?static?Singleton?instance;
????????
private?static?readonly?object?syncRoot?=?new?object();
????????
private?Singleton()
????????
{
????????}

????????
public?static?Singleton?GetInstance()
????????
{
????????????
lock?(syncRoot)
????????????
{
????????????????
if?(instance?==?null)
????????????????
{
????????????????????instance?
=?new?Singleton();
????????????????}

????????????}

????????????
return?instance;
????????}

????}

????上面的代碼中的對象實例由最先進(jìn)入的那個線程創(chuàng)建,以后的線程在進(jìn)入時不會再去創(chuàng)建對象實例了。由于有了Lock,就保證了多線程環(huán)境下的同時訪問也不會造成多個實例的生成。
????我們不經(jīng)要問,為什么不直接lock呢,而是創(chuàng)建一個SyncRoot來Lock呢?因為在我們加鎖的時候,instance實例有沒有被創(chuàng)建過實例我們都還不知道呢,我們不可能對其加鎖的。上面我們=每次調(diào)用GetInstance()方法時,都需要Lock,這樣會影響性能的。所以我們再做一定的改良優(yōu)化,看下面的代碼:
Singleton
????public?class?Singleton
????
{
????????
private?static?Singleton?instance;
????????
private?static?readonly?object?syncRoot?=?new?object();
????????
private?Singleton()
????????
{
????????}

????????
public?static?Singleton?GetInstance()
????????
{
????????????
if?(instance?==?null)
????????????
{
????????????????
lock?(syncRoot)
????????????????
{
????????????????????
if?(instance?==?null)
????????????????????
{
????????????????????????instance?
=?new?Singleton();
????????????????????}

????????????????}

????????????}

????????????
return?instance;
????????}

????}
????現(xiàn)在,我們就不用讓線程每次都加鎖了,而只是在實例未被創(chuàng)建的時候才加鎖,同時也保證了多線程的安全,這種做法就是Double-Check Locking (雙重鎖定)。到這兒我們不經(jīng)會問,我在外面已經(jīng)判斷了instance實例是否存在,為什么在lock里面還要判斷呢?我們具體的來分析,對于instance存在的情況,就直接返回,這沒有問題,當(dāng)instance位null并且同時有兩個線程調(diào)用GetInstance()方法時,他們同時會通過第一重判斷,然后由于Lock機(jī)制,則這兩個線程只能進(jìn)入一個,另一個則只能排隊等候,必須其中一個進(jìn)入并出來后,他才能進(jìn)入。而此時如果沒有了第二重的判斷,則第一個線程創(chuàng)建了實例,而第二個線程還是可以繼續(xù)創(chuàng)建新的實例,這樣就沒有達(dá)到單例模式的目的。
????3.靜態(tài)初始化
????在.Net中公共語言運(yùn)行庫中也提供了一種“靜態(tài)初始化”方法,這種方法不需要顯示的編寫線程安全代碼,即可解決多線程環(huán)境下單例模式不安全的問題.看下面簡單的代碼:
Singleton
????public?sealed?class?Singleton
????
{
????????
private?static?readonly?Singleton?instance?=?new?Singleton();
????????
private?Singleton()?{?}
????????
public?static?Singleton?GetInstance()
????????
{
????????????
return?instance;
????????}

????}
????這種靜態(tài)初始化的方法是自己被加載時就自己實例化,被形象的稱之為惡漢式單例類。而原先的單例模式處理方式要在第一次被引用的時候才會被實例化,就被稱為懶漢式單例類。
????3.總結(jié)
????全局變量與單例模式:單例模式維護(hù)了自身的實例化,在使用上是安全的,一個全局對象無法自行維護(hù),也就無法規(guī)避重復(fù)創(chuàng)建對象實例,系統(tǒng)資源會被大量占用,更糟糕的是會出現(xiàn)邏輯問題。
????單件與實用類中的靜態(tài)方法:
????實用類是提供系統(tǒng)公用的靜態(tài)方法,并且也經(jīng)常采用私有的構(gòu)造方法,與單例不同,他沒有實例,其中的方法全是靜態(tài)方法。實用類和單例模式的區(qū)別如下:
????1).實用類不保存狀態(tài),僅提供功能。2)實用類不具有多態(tài)性,而單例類可以有子類。3)單例是對象,而實用類只是方法的集合。

轉(zhuǎn)載于:https://www.cnblogs.com/peida/archive/2008/06/27/1230756.html

總結(jié)

以上是生活随笔為你收集整理的设计模式学习笔记十:单例模式(Singleton Pattern)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。