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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

细颗粒度Singleton模式实现

發(fā)布時(shí)間:2025/6/17 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 细颗粒度Singleton模式实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作為一個(gè)很典型的設(shè)計(jì)模式,Singleton模式常常被用來展示設(shè)計(jì)模式的技巧,并且隨著技術(shù)的演進(jìn),.NET語言和Java都已經(jīng)把經(jīng)典《Design Patterns : Elements of Reusable Object-Oriented Software》中所定義的Singleton模式作了完善,例如C#可以通過這樣一個(gè)非常精簡(jiǎn)但又很完美的方式實(shí)現(xiàn)了一個(gè)進(jìn)程內(nèi)部線程安全的Singleton模式。

C#?最經(jīng)典Singleton模式的實(shí)現(xiàn)(Lazy構(gòu)造方式)public?class?Singleton
{
????
private?static?Singleton?instance;???//?唯一實(shí)例
????protected?Singleton()?{?}???//?封閉客戶程序的直接實(shí)例化
????public?static?Singleton?Instance????
????{
????????
get
????????{
????????????
if?(instance?==?null)
????????????????instance?
=?new?Singleton();
????????????
return?instance;
????????}
????}

}?

C# 通過Double Check實(shí)現(xiàn)的相對(duì)線程安全的Singleton模式?

public?class?Singleton
{
????
protected?Singleton()?{?}
????
private?static?volatile?Singleton?instance?=?null;
????
///?Lazy方式創(chuàng)建唯一實(shí)例的過程
????public?static?Singleton?Instance()
????{
????????
if?(instance?==?null)???????????//?外層if
????????????lock?(typeof(Singleton))????//?多線程中共享資源同步
????????????????if?(instance?==?null)???//?內(nèi)層if
????????????????????instance?=?new?Singleton();
????????
return?instance;
????}

}?

C#充分依靠語言特性實(shí)現(xiàn)的間接版Singleton模式

class?Singleton
{
????
private?Singleton()?{?}
????
public?static?readonly?Singleton?Instance?=?new?Singleton();

}?

但項(xiàng)目中我們往往需要更粗或者更細(xì)顆粒度的Singleton,比如某個(gè)線程是長時(shí)間運(yùn)行的后臺(tái)任務(wù),它本身存在很多模塊和中間處理,但每個(gè)線程都希望有自己的線程內(nèi)單獨(dú)Singleton對(duì)象,其他線程也獨(dú)立操作自己的線程內(nèi)Singleton,所謂的線程級(jí)Singleton其實(shí)他的實(shí)例總數(shù) = 1(每個(gè)線程內(nèi)部唯一的一個(gè)) * N (線程數(shù))= N。

.NET程序可以通過把靜態(tài)成員標(biāo)示為System. ThreadStaticAttribute就可以確保它指示靜態(tài)字段的值對(duì)于每個(gè)線程都是唯一的。但這對(duì)于Windows Form程序很有效,對(duì)于Web Form、ASP.NET Web Service等Web類應(yīng)用不適用,因?yàn)樗麄兪窃谕粋€(gè)IIS線程下分割的執(zhí)行區(qū)域,客戶端調(diào)用時(shí)傳遞的對(duì)象是在HttpContext中共享的,也就是說它本身不可以簡(jiǎn)單地通過System. ThreadStaticAttribute實(shí)現(xiàn)。不僅如此,使用System. ThreadStaticAttribute也不能很瀟灑的套用前面的內(nèi)容寫成:

C#
[ThreadStatic]
public?static?readonly?Singleton?Instance?=?new?Singleton();

因?yàn)榘凑?NET的設(shè)計(jì)要求不要為標(biāo)記為它的字段指定初始值,因?yàn)檫@樣的初始化只會(huì)發(fā)生一次,因此在類構(gòu)造函數(shù)執(zhí)行時(shí)只會(huì)影響一個(gè)線程。在不指定初始值的情況下,如果它是值類型,可依賴初始化為其默認(rèn)值的字段,如果它是引用類型,則可依賴初始化為null。也就是說多線程情況下,除了第一個(gè)實(shí)例外,其他線程雖然也期望通過這個(gè)方式獲得唯一實(shí)例,但其實(shí)獲得就是一個(gè)null,不能用。

解決Windows Form下的細(xì)顆粒度Singleton問題

對(duì)于Windows Forms下的情況,可以通過System. ThreadStaticAttribute比較容易的高速CLR其中的靜態(tài)唯一屬性Instance僅在本線程內(nèi)部靜態(tài),但麻煩的是怎么構(gòu)造它,正如上面背景介紹部分所說,不能把它放到整個(gè)類的靜態(tài)構(gòu)造函數(shù)里,也不能直接初始化,那么怎么辦?還好,那個(gè)很cool的實(shí)現(xiàn)這里不適用的話,我們就退回到最經(jīng)典的那個(gè)lazy方式加載Singleton實(shí)例的方法。你可能覺得,這線程不安全了吧?那種實(shí)現(xiàn)方式確實(shí)不是線程安全,但我們這里的Singleton構(gòu)造本身就已經(jīng)運(yùn)行在一個(gè)線程里面了,用那種不安全的方式在線程內(nèi)部實(shí)現(xiàn)只有自己“一畝三分地”范圍內(nèi)Singleton的對(duì)象反而安全了。新的實(shí)現(xiàn)如下:

public?class?Singleton
{
????
private?Singleton()?{?}

????[ThreadStatic]??
//?說明每個(gè)Instance僅在當(dāng)前線程內(nèi)靜態(tài)
????private?static?Singleton?instance;

????
public?static?Singleton?Instance
????{
????????
get
????????{
????????????
if?(instance?==?null)
????????????????instance?
=?new?Singleton();
????????????
return?instance;
????????}
????}

}?

Unit Test
///?每個(gè)線程需要執(zhí)行的目標(biāo)對(duì)象定義///?同時(shí)在它內(nèi)部完成線程內(nèi)部是否Singleton的情況
class?Work
{
????
public?static?IList?Log?=?new?List();
????
///?每個(gè)線程的執(zhí)行部分定義
????public?void?Procedure()
????{
????????Singleton?s1?
=?Singleton.Instance;
????????Singleton?s2?
=?Singleton.Instance;
????????
//?證明可以正常構(gòu)造實(shí)例
????????Assert.IsNotNull(s1);
????????Assert.IsNotNull(s2);
????????
//?驗(yàn)證當(dāng)前線程執(zhí)行體內(nèi)部?jī)纱我玫氖欠駷橥粋€(gè)實(shí)例
????????Assert.AreEqual(s1.GetHashCode(),?s2.GetHashCode());
????????
//登記當(dāng)前線程所使用的Singleton對(duì)象標(biāo)識(shí)
????????Log.Add(s1.GetHashCode());
????}
}

[TestClass]
public?class?TestSingleton
{
????
private?const?int?ThreadCount?=?3;
????[TestMethod]
????
public?void?Test()
????{
????????
//?創(chuàng)建一定數(shù)量的線程執(zhí)行體
????????Thread[]?threads?=?new?Thread[ThreadCount];
????????
for?(int?i?=?0;?i?<?ThreadCount;?i++)
????????{
????????????ThreadStart?work?
=?new?ThreadStart((new?Work()).Procedure);
????????????threads[i]?
=?new?Thread(work);
????????}
????????
//?執(zhí)行線程
????????foreach?(Thread?thread?in?threads)?thread.Start();

????????
//?終止線程并作其他清理工作
????????
//?...?...

????????
//?判斷是否不同線程內(nèi)部的Singleton實(shí)例是不同的
????????for?(int?i?=?0;?i?<?ThreadCount?-?1;?i++)
????????????
for?(int?j?=?i?+?1;?j?<?ThreadCount;?j++)
????????????????Assert.AreNotEqual(Work.Log[i],?Work.Log[j]);
????}
}

下面我們分析一下單元測(cè)試代碼說明的問題:

  • 在Work.Procedure()方法中,兩次調(diào)用到了Singleton類的Instance靜態(tài)屬性,經(jīng)過驗(yàn)證是同一個(gè)Singleton類實(shí)例。同時(shí)由于Singleton類的構(gòu)造函數(shù)定義為私有,所以線程(客戶程序)無法自己實(shí)例化Singleton類,因此同時(shí)滿足該模式的設(shè)計(jì)意圖;
  • 通過對(duì)每個(gè)線程內(nèi)部使用的Singleton實(shí)例登記并檢查,確認(rèn)不同線程內(nèi)部其實(shí)掌握的是不同實(shí)例的引用,因此滿足我們需要實(shí)現(xiàn)的細(xì)顆粒度(線程級(jí))的意圖;
  • 解決Web Form下細(xì)顆粒度Singleton問題。

上面用ThreadStatic雖然解決了Windows Form的問題,但對(duì)于Web Form應(yīng)用而言并不適用,原因是Web Form應(yīng)用中每個(gè)會(huì)話的本地全局區(qū)域不是線程,而是自己的HttpContext,因此相應(yīng)的Singleton實(shí)例也應(yīng)該保存在這個(gè)位置。實(shí)現(xiàn)上我們只需要做少許的修改,就可以完成一個(gè)Web Form下的細(xì)顆粒度Singleton設(shè)計(jì):

注:這里的Web Form應(yīng)用包括ASP.NET Application、ASP.NET Web Service、ASP.NET AJAX等相關(guān)應(yīng)用。但示例并沒有在.NET Compact Framework和.NET Micro Framework的環(huán)境下進(jìn)行過驗(yàn)證。

public?class?Singleton
{
????
///?足夠復(fù)雜的一個(gè)key值,用于和HttpContext中的其他內(nèi)容相區(qū)別
????private?const?string?Key?=?"just.complicated..singleton";
????
private?Singleton()?{?}

????
public?static?Singleton?Instance
????{
????????
get
????????{
????????????
//?基于HttpContext的Lazy實(shí)例化過程
????????????Singleton?instance?=?(Singleton)HttpContext.Current.Items[Key];
????????????
if?(instance?==?null)
????????????{
????????????????instance?
=?new?Singleton();
????????????????HttpContext.Current.Items[Key]?
=?instance;
????????????}
????????????
return?instance;
????????}
????}

}?

//Unit?Test
using?System;
using?System.Web;
using?MarvellousWorks.PracticalPattern.SingletonPattern.WebContext;
using?Microsoft.VisualStudio.TestTools.UnitTesting;
namespace?SingletonPattern.Test.Web
{
????
public?partial?class?_Default?:?System.Web.UI.Page
????{
????????
protected?void?Page_Load(object?sender,?EventArgs?e)
????????{
????????????Singleton?s1?
=?Singleton.Instance;
????????????Singleton?s2?
=?Singleton.Instance;
????????????
//?確認(rèn)獲得的Singleton實(shí)例引用確實(shí)已經(jīng)被實(shí)例化了
????????????Assert.IsNotNull(s1);
????????????Assert.IsNotNull(s2);
????????????
//?確認(rèn)兩個(gè)引用調(diào)用的是同一個(gè)Singleton實(shí)例
????????????Assert.AreEqual(s1.GetHashCode(),?s2.GetHashCode());
????????????
//?顯示出當(dāng)前Singleton實(shí)例的標(biāo)識(shí),用于比較與其他
????????????
//?HttpContext環(huán)境下的Singleton實(shí)例其實(shí)是不同的實(shí)例
????????????instanceHashCode.Text?=?s1.GetHashCode().ToString();
????????}
????}
}
瀏覽器效果

同上,這段單元測(cè)試驗(yàn)證了Web Form下的細(xì)顆粒度Singleton,通過將唯一實(shí)例的存儲(chǔ)位置從當(dāng)前線程遷移到HttpContext,一樣可以實(shí)現(xiàn)細(xì)顆粒度的Singleton設(shè)計(jì)意圖。

更通用的細(xì)顆粒度Singleton

但如果你是一個(gè)公共庫或者是公共平臺(tái)的設(shè)計(jì)者,您很難預(yù)料到自己的類庫會(huì)運(yùn)行在Windows Form還是Web Form環(huán)境下,但Singleton模式作為很多公共機(jī)制,最常用的包括技術(shù)器、時(shí)鐘等等又常常會(huì)成為其他類庫的基礎(chǔ),尤其當(dāng)涉及到業(yè)務(wù)領(lǐng)域邏輯的時(shí)候,很難在開發(fā)過程就約定死運(yùn)行的模式。怎么辦?

這里借助一個(gè)工具類,通過它判斷當(dāng)前執(zhí)行環(huán)境是Web Form還是Windows Form,然后作一個(gè)2 in 1的細(xì)顆粒度Singleton(,聽起來有點(diǎn)象早年的任天堂游戲卡),不過就像我們提到的面向?qū)ο笤O(shè)計(jì)的單一職責(zé)原則一樣,把兩個(gè)和在一起會(huì)產(chǎn)生一些比較難看的冗余代碼,但Singleton與其他設(shè)計(jì)模式有個(gè)很顯著的區(qū)別——他不太希望被外部機(jī)制實(shí)例化,因?yàn)樗3謱?shí)例的唯一性,因此一些常用的依賴倒置技巧在這里又顯得不太適用。這里實(shí)現(xiàn)一個(gè)稍有些冗余的Web Form + Windows Form 2 in 1的細(xì)顆粒度Singleton如下:

UML

C# 工具類GenericContext

///?判斷當(dāng)前應(yīng)用是否為Web?應(yīng)用的Helper?方法(非官方方法)
private?static?bool?CheckWhetherIsWeb()
{
????
bool?result?=?false;
????AppDomain?domain?
=?AppDomain.CurrentDomain;
????
try
????{
????????
if?(domain.ShadowCopyFiles)
????????????result?
=?(HttpContext.Current.GetType()?!=?null);
????}
????
catch?(System.Exception){}
????
return?result;

}?

//C#?2in?1的細(xì)顆粒度Singleton模式實(shí)現(xiàn)
using?System;
using?System.Web;
using?MarvellousWorks.PracticalPattern.Common;
namespace?MarvellousWorks.PracticalPattern.SingletonPattern.Combined
{
????
public?class?Singleton
????{
????????
private?const?string?Key?=?"marvellousWorks.practical.singleton";
????????
private?Singleton()?{?}?????//?對(duì)外封閉構(gòu)造
????????[ThreadStatic]
????????
private?static?Singleton?instance;

????????
public?static?Singleton?Instance
????????{
????????????
get
????????????{
????????????????
//?通過之前準(zhǔn)備的GenericContext中非官方的方法
????????????????
//?判斷當(dāng)前執(zhí)行模式是Web?Form還是非Web?Form
????????????????
//?本方法沒有在?.NET?的?CF?和?MF?上驗(yàn)證過
????????????????if?(GenericContext.CheckWhetherIsWeb())?????//?Web?Form
????????????????{
????????????????????
//?基于HttpContext的Lazy實(shí)例化過程
????????????????????Singleton?instance?=?(Singleton)HttpContext.Current.Items[Key];
????????????????????
if?(instance?==?null)
????????????????????{
????????????????????????instance?
=?new?Singleton();
????????????????????????HttpContext.Current.Items[Key]?
=?instance;
????????????????????}
????????????????????
return?instance;
????????????????}
????????????????
else??//?非Web?Form方式
????????????????{
????????????????????
if?(instance?==?null)
????????????????????????instance?
=?new?Singleton();
????????????????????
return?instance;
????????????????}
????????????}
????????}
????}
}

小結(jié)

設(shè)計(jì)模式中很多意圖部分表述的要求其實(shí)也都是有語意范圍 的,比如說“唯一”、“所有相關(guān)”、“一系列相互依賴的”等,但項(xiàng)目中往往有自己定制化的要求,可能的話建議盡量用語言、語言運(yùn)行環(huán)境的特性完成這些工作。

?原文地址:
http://www.infoq.com/cn/articles/fine-grained-singleton-pattern


轉(zhuǎn)載于:https://www.cnblogs.com/jeriffe/articles/2142996.html

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的细颗粒度Singleton模式实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 成年人三级网站 | 免费视频一二三区 | 国产三级精品视频 | 1024视频在线| 邻居校草天天肉我h1v1 | 欧美精品乱码视频一二专区 | 99精品福利视频 | 亚洲福利视频一区二区三区 | 在线中文字幕一区 | 国产美女无遮挡永久免费观看 | 久久国产一 | 美国少妇在线观看免费 | 秘密的基地 | 精品久久BBBBB精品人妻 | 成人在线免费视频观看 | 精品二区视频 | 亚洲毛茸茸 | 亚洲超碰在线观看 | 这里有精品视频 | jizzjizz在线| 欧美涩涩涩| 爱爱视频网址 | 亚洲男人天堂视频 | 国产真人无遮挡作爱免费视频 | 久久草av | 国产精品福利一区二区三区 | 嫩草视频入口 | 日韩精品视频在线播放 | 久久怡春院 | 天堂精品久久 | 免费黄色入口 | 大地av | 欧美一区二区区 | 人人澡人人澡 | 无码无遮挡又大又爽又黄的视频 | 亚洲AV成人无码网站天堂久久 | 麻豆影视免费观看 | 成年人黄色录像 | 香蕉伊人网 | 香蕉啪啪网| 天堂在线免费视频 | 岛国av免费看 | 国产欧美日韩专区 | 免费在线观看黄色网址 | 国产农村av| 精品久久在线观看 | 久久久久亚洲av无码专区体验 | 国产精品一区一区三区 | 桃谷绘里香在线观看 | 在线观看国产一区二区 | 国产精品午夜未成人免费观看 | 婷婷777 | 三级国产网站 | 69亚洲乱人伦 | 五月婷婷开心 | 在线第一页| 99久久99久久精品免费看蜜桃 | 欧美婷婷精品激情 | 无码少妇一级AV片在线观看 | 国产极品美女高潮无套在线观看 | 日本精品视频一区二区 | av88av| 国产xxxxwwww| 美女隐私免费 | 久久精品—区二区三区舞蹈 | 五月天社区 | 720url在线观看免费版 | 黄色片子视频 | 亚洲天堂视频网站 | 久久艹在线 | 木下凛凛子av一区二区三区 | 神马午夜电影一区二区三区在线观看 | 欧美人妻一区二区三区 | 亚洲午夜在线播放 | 免费日韩精品 | 超碰久草 | 欧美韩一区| 爱情岛av永久入口 | 91.xxx.高清在线 | jizz免费 | 真实偷拍激情啪啪对白 | 女人洗澡一级特黄毛片 | 日本高清不卡二区 | 尤物视频在线观看免费 | 欧美一级久久久 | 杨幂一区二区国产精品 | 国产精品久久久久久久久免费 | 黄色av高清 | 免费毛片在线播放免费 | 在线无码va中文字幕无码 | 日韩欧美精品免费 | 欧美人交a欧美精品 | 国产一级网站 | 免费观看全黄做爰的视频 | a级片国产| 天天色综 | 成年人网站在线 | 9l蝌蚪porny中文自拍 | 精品国产www|