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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

asp.net

手撕设计模式之「单例模式」(详细解析)

發(fā)布時(shí)間:2025/3/20 asp.net 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手撕设计模式之「单例模式」(详细解析) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

單例模式主要用來(lái)保證系統(tǒng)中某個(gè)類(lèi)的實(shí)例對(duì)象的唯一性,是最簡(jiǎn)單的一種設(shè)計(jì)模式,而且在面試中也經(jīng)常會(huì)被問(wèn)到,是非常值得我們?nèi)W(xué)習(xí)的。如果你們面試遇到了哪些設(shè)計(jì)模式的考察,也歡迎留言,我會(huì)及時(shí)發(fā)新的博文。

文章目錄

  • 前言
  • 1. 模式定義
  • 2. 模式實(shí)現(xiàn)
  • 3. 單例模式的拓展
    • 3.1 懶漢式單例
    • 3.2 餓漢式單例
  • 4. 多線程環(huán)境中的單例模式
    • 4.1 延時(shí)加載
    • 4.2 雙重校驗(yàn)鎖
    • 4.3 靜態(tài)內(nèi)部類(lèi)
  • 參考資料

1. 模式定義

單例模式(Singleton Pattern):確保某一個(gè)類(lèi)只有一個(gè)實(shí)例,而且自行實(shí)例化并像整個(gè)系統(tǒng)提供這個(gè)實(shí)例,這個(gè)類(lèi)稱(chēng)為單例類(lèi),它會(huì)提供全局訪問(wèn)的方法。單例模式是對(duì)象創(chuàng)建型模式的一種。

單例模式的三個(gè)要點(diǎn):

  • 某個(gè)類(lèi)只能有一個(gè)實(shí)例
  • 必須自行創(chuàng)建這個(gè)實(shí)例
  • 必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例

2. 模式實(shí)現(xiàn)

要想實(shí)現(xiàn)單例模式,我們可以從它的三個(gè)要點(diǎn)入手:

首先是單例的唯一性,既然單例是唯一的,我們毫無(wú)疑問(wèn)應(yīng)該給他加上 static 關(guān)鍵字,又因?yàn)檫@個(gè)對(duì)象不應(yīng)該直接暴露,所以還要加上 private 進(jìn)行訪問(wèn)限定。

private static Singleton instince = null;

接著,就是這個(gè)對(duì)象需要由單例類(lèi)自行創(chuàng)建,這時(shí)我們就應(yīng)該屏蔽外界訪問(wèn)該類(lèi)初始化方法的接口,也就是用 private 修飾構(gòu)造函數(shù)。

private Singleton() { }

最后一點(diǎn)就比較容易實(shí)現(xiàn)了,給公有工廠方法 static 關(guān)鍵字,即可實(shí)現(xiàn)向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。

public static Singleton getInstance() {if (instance == null) {instince = new Singleton();}return instance; }

將以上代碼整合一下,就可以得到如下的單例模式的代碼實(shí)現(xiàn)模板:

public class Singleton {//靜態(tài)私有成員變量,保證實(shí)例的唯一性private static Singleton instince = null;//私有構(gòu)造函數(shù),保證實(shí)例由類(lèi)自行創(chuàng)建private Singleton() {}// 靜態(tài)公有工廠方法,向系統(tǒng)提供這個(gè)唯一實(shí)例public static Singleton getInstance() {if (instance == null) {instince = new Singleton();}return instance;} }

下面是針對(duì)上面單例模式實(shí)現(xiàn)模板的客戶端測(cè)試代碼:

public Client {public static void main(String []args) {Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();System.out.println(s1 == s2); //true} }

3. 單例模式的拓展

單例模式可以分為懶漢式單例餓漢式單例,它們的區(qū)別主要在單例類(lèi)對(duì)象的初始化時(shí)間上。下面我們來(lái)詳細(xì)講解:

3.1 懶漢式單例

懶漢式單例模式的結(jié)構(gòu)圖如下圖所示:

在模式圖中,我們可以看到這實(shí)例對(duì)象在創(chuàng)建類(lèi)的時(shí)候并沒(méi)有初始化,而是等到有人調(diào)用getInstance()方法獲取實(shí)例的時(shí)候才進(jìn)行實(shí)例對(duì)象的初始化,這也恰恰體現(xiàn)了懶漢式的這種“懶惰行為”。

下面是以“身份證號(hào)碼類(lèi)”作為例子,編寫(xiě)的懶漢式單例代碼。

public class IdentityCardNo {private String no;//某個(gè)類(lèi)只能有一個(gè)實(shí)例private static IdentityCardNo instince = null;//必須自行創(chuàng)建這個(gè)實(shí)例private IdentityCardNo() {}//必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例public static IdentityCardNo getInstance() {if (instince == null) {System.out.println("第一次辦理身份證,分配新號(hào)碼");instince = new IdentityCardNo();instince.setIdentityCardNo("400000199710301111");} else {System.out.println("重復(fù)辦理身份證,獲取舊號(hào)碼");}return instince;}public String getIdentityCardNo() {return no;}public void setIdentityCardNo(String no) {this.no = no;} }

可以仿造上面的方法,寫(xiě)一個(gè)Client類(lèi)來(lái)進(jìn)行檢驗(yàn)。

3.2 餓漢式單例

餓漢式單例模式的結(jié)構(gòu)圖如下圖所示:

由于餓漢式單例的“饑餓”特性,使得它在類(lèi)加載階段就對(duì)單例類(lèi)對(duì)象進(jìn)行了初始化,從上面的結(jié)構(gòu)圖也可以看出這一點(diǎn)。

下面代碼是上面那個(gè)例子的餓漢式實(shí)現(xiàn):

public class IdentityCardNo {private String no;//某個(gè)類(lèi)只能有一個(gè)實(shí)例private static IdentityCardNo instince = new IdentityCardNo();//必須自行創(chuàng)建這個(gè)實(shí)例private IdentityCardNo() {System.out.println("第一次辦理身份證,分配新號(hào)碼");}//必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例public static IdentityCardNo getInstance() {instince.setIdentityCardNo("400000199710301111");return instince;}public String getIdentityCardNo() {return no;}public void setIdentityCardNo(String no) {this.no = no;} }

4. 多線程環(huán)境中的單例模式

上面提到的懶漢式單例是線程不安全的,在多線程的環(huán)境下,對(duì)象的唯一性得不到保障。于是就有了下面幾種線程安全的單例模式實(shí)現(xiàn)方法,其中第1,2種方法是對(duì)懶漢式的改進(jìn),第 3 中是對(duì)餓漢式的改進(jìn)。

4.1 延時(shí)加載

我們可以用synchronized關(guān)鍵字修飾getInstance()方法,利用延時(shí)加載的方式保證在多線程環(huán)境下對(duì)象的唯一性。但是這種方法在容易造成線程擁塞,效率不高。

實(shí)現(xiàn)代碼如下:

public class Singleton {private static Singleton instince = null;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instince = new Singleton();}return instance;} }

4.2 雙重校驗(yàn)鎖

這種方式采用雙鎖機(jī)制,線程安全且在多線程情況下能保持高性能,是比較推薦使用的方法。

實(shí)現(xiàn)代碼如下:

public class Singleton {private static Singleton instince = null;private Singleton() {}public static Singleton getInstance() {if (instance == null) {//只將synchronized關(guān)鍵字用在了初始化模塊synchronized (Singleton.class) {if (install == null) {instince = new Singleton();}}}return instance;} }

4.3 靜態(tài)內(nèi)部類(lèi)

這種方式通過(guò)給對(duì)象加上final關(guān)鍵字修飾,能達(dá)到雙檢鎖方式一樣的功效,但實(shí)現(xiàn)更簡(jiǎn)單。對(duì)靜態(tài)域使用延遲初始化,應(yīng)使用這種方式而不是雙檢鎖方式。這種方式只適用于靜態(tài)域的情況,雙檢鎖方式可在實(shí)例域需要延遲初始化時(shí)使用。

實(shí)現(xiàn)代碼如下:

public class Singleton {private static final Singleton instince = new Singleton();private Singleton() {}public static Singleton getInstance() {return Singleton.instance;} }

參考資料

  • 單例模式| 菜鳥(niǎo)教程
  • 《Java設(shè)計(jì)模式》
  • Java實(shí)現(xiàn)單例模式 | CSDN
  • 總結(jié)

    以上是生活随笔為你收集整理的手撕设计模式之「单例模式」(详细解析)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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