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

歡迎訪問 生活随笔!

生活随笔

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

asp.net

单例设计模式示例

發(fā)布時(shí)間:2023/12/3 asp.net 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单例设计模式示例 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文是我們名為“ Java設(shè)計(jì)模式 ”的學(xué)院課程的一部分。

在本課程中,您將深入研究大量的設(shè)計(jì)模式,并了解如何在Java中實(shí)現(xiàn)和利用它們。 您將了解模式如此重要的原因,并了解何時(shí)以及如何應(yīng)用模式中的每一個(gè)。 在這里查看 !

目錄

1.單例模式 2.如何使用單例模式創(chuàng)建類 3.何時(shí)使用Singleton 4.下載源代碼

1.單例模式

有時(shí)對(duì)于某些類來說,只有一個(gè)實(shí)例很重要。 有許多對(duì)象,我們只需要它們的一個(gè)實(shí)例,如果實(shí)例化多個(gè)對(duì)象,我們將遇到各種問題,例如程序行為不正確,資源過度使用或結(jié)果不一致。

您可能只需要一個(gè)類的對(duì)象,例如,當(dāng)您創(chuàng)建應(yīng)用程序的上下文時(shí),或者線程可管理的池,注冊(cè)表設(shè)置,連接到輸入或輸出控制臺(tái)的驅(qū)動(dòng)程序等。該類型顯然會(huì)導(dǎo)致程序不一致。

Singleton模式可確保一個(gè)類只有一個(gè)實(shí)例,并提供對(duì)其的全局訪問點(diǎn)。 但是,盡管就類圖而言,單例是最簡(jiǎn)單的,因?yàn)橹挥幸粋€(gè)類,但其實(shí)現(xiàn)卻有些棘手。

圖1

在本課程中,我們將嘗試不同的方法來僅創(chuàng)建類的單個(gè)對(duì)象,還將了解一種方法比另一種方法更好。

2.如何使用單例模式創(chuàng)建類

創(chuàng)建這種類型的類的方法有很多種,但仍然可以看到一種方法比另一種方法更好。

讓我們從一個(gè)簡(jiǎn)單的方法開始。

如果提供一個(gè)使對(duì)象可訪問的全局變量該怎么辦? 例如:

package com.javacodegeeks.patterns.singletonpattern;public class SingletonEager {public static SingletonEager sc = new SingletonEager();}

眾所周知,一個(gè)類的靜態(tài)變量只有一個(gè)副本,我們可以應(yīng)用它。 就目前而言,客戶端代碼使用此sc靜態(tài)變量就可以了。 但是,如果客戶端使用新的運(yùn)算符,則將有此類的新實(shí)例。

要停止在類之外實(shí)例化該類,讓我們將該類的構(gòu)造函數(shù)設(shè)為私有。

package com.javacodegeeks.patterns.singletonpattern;public class SingletonEager {public static SingletonEager sc = new SingletonEager();private SingletonEager(){}}

這行得通嗎? 我想是的。 通過使構(gòu)造函數(shù)保持私有狀態(tài),其他任何類都不能實(shí)例化該類。 獲取此類的唯一方法是使用sc靜態(tài)變量,該變量確保只有一個(gè)對(duì)象存在。

但是,眾所周知,直接訪問類成員不是一個(gè)好主意。 我們將提供一種方法,通過該方法,sc變量將獲得訪問權(quán),而不是直接訪問。

package com.javacodegeeks.patterns.singletonpattern;public class SingletonEager {private static SingletonEager sc = new SingletonEager();private SingletonEager(){}public static SingletonEager getInstance(){return sc;} }

因此,這是我們的單例類,可確保僅創(chuàng)建該類的一個(gè)對(duì)象,即使存在多個(gè)請(qǐng)求,也將僅返回相同的實(shí)例化對(duì)象。

這種方法的一個(gè)問題是,一旦將類加載到JVM中,就會(huì)立即創(chuàng)建對(duì)象。 如果從未請(qǐng)求過該對(duì)象,則內(nèi)存中將有一個(gè)無用的對(duì)象。

在需要時(shí)創(chuàng)建對(duì)象始終是一種好方法。 因此,我們將在第一個(gè)調(diào)用上創(chuàng)建一個(gè)對(duì)象,然后在其他后續(xù)調(diào)用上返回相同的對(duì)象。

package com.javacodegeeks.patterns.singletonpattern;public class SingletonLazy {private static SingletonLazy sc = null;private SingletonLazy(){}public static SingletonLazy getInstance(){if(sc==null){sc = new SingletonLazy();}return sc;} }

在getInstance()方法中,我們檢查靜態(tài)變量sc是否為null,然后實(shí)例化該對(duì)象并將其返回。 因此,在第一次調(diào)用時(shí),如果sc為null,則將創(chuàng)建對(duì)象,而在接下來的后續(xù)調(diào)用中,它將返回相同的對(duì)象。

這看起來確實(shí)不錯(cuò),不是嗎? 但是,此代碼將在多線程環(huán)境中失敗。 想象兩個(gè)線程同時(shí)訪問該類,線程t1首次調(diào)用getInstance()方法,它檢查靜態(tài)變量sc是否為null,然后由于某種原因而被中斷。 另一個(gè)線程t2調(diào)用getInstance()方法成功通過了if檢查并實(shí)例化了該對(duì)象。 然后,線程t1醒來,它還創(chuàng)建了對(duì)象。 此時(shí),將有兩個(gè)此類。

為了避免這種情況,我們將使用synchronized關(guān)鍵字到getInstance()方法。 通過這種方式,我們強(qiáng)制每個(gè)線程等待其輪流才能進(jìn)入該方法。 因此,沒有兩個(gè)線程會(huì)同時(shí)進(jìn)入該方法。 同步帶有價(jià)格,它將降低性能,但是如果對(duì)getInstance()方法的調(diào)用不會(huì)給您的應(yīng)用程序造成實(shí)質(zhì)性開銷,則請(qǐng)忽略它。 另一個(gè)解決方法是轉(zhuǎn)向渴望的實(shí)例化方法,如前面的示例所示。

package com.javacodegeeks.patterns.singletonpattern;public class SingletonLazyMultithreaded {private static SingletonLazyMultithreaded sc = null;private SingletonLazyMultithreaded(){}public static synchronized SingletonLazyMultithreaded getInstance(){if(sc==null){sc = new SingletonLazyMultithreaded();}return sc;} }

但是,如果要使用同步,則有另一種稱為“雙重檢查鎖定”的技術(shù)可以減少同步的使用。 使用雙重檢查鎖定,我們首先檢查是否創(chuàng)建了實(shí)例,如果沒有創(chuàng)建,則進(jìn)行同步。 這樣,我們只同步第一次。

package com.javacodegeeks.patterns.singletonpattern;public class SingletonLazyDoubleCheck {private volatile static SingletonLazyDoubleCheck sc = null;private SingletonLazyDoubleCheck(){}public static SingletonLazyDoubleCheck getInstance(){if(sc==null){synchronized(SingletonLazyDoubleCheck.class){if(sc==null){sc = new SingletonLazyDoubleCheck();} }}return sc;} }

除此之外,還有其他打破單例模式的方法。

  • 如果該類是Serializable。
  • 如果是可克隆的。
  • 可以通過反思來打破。
  • 同樣,如果該類由多個(gè)類加載器加載。
  • 下面的示例說明如何保護(hù)您的類免于被多次實(shí)例化。

    package com.javacodegeeks.patterns.singletonpattern;import java.io.ObjectStreamException; import java.io.Serializable;public class Singleton implements Serializable{private static final long serialVersionUID = -1093810940935189395L;private static Singleton sc = new Singleton();private Singleton(){if(sc!=null){throw new IllegalStateException("Already created.");}}public static Singleton getInstance(){return sc;}private Object readResolve() throws ObjectStreamException{return sc;}private Object writeReplace() throws ObjectStreamException{return sc;}public Object clone() throws CloneNotSupportedException{throw new CloneNotSupportedException("Singleton, cannot be clonned");}private static Class getClass(String classname) throws ClassNotFoundException {ClassLoader classLoader = Thread.currentThread().getContextClassLoader();if(classLoader == null) classLoader = Singleton.class.getClassLoader();return (classLoader.loadClass(classname));}}
  • 在您的單例類中實(shí)現(xiàn)readResolve()和writeReplace()方法,并通過它們返回相同的對(duì)象。
  • 您還應(yīng)該實(shí)現(xiàn)clone()方法并引發(fā)異常,以使單例無法被克隆。
  • 構(gòu)造函數(shù)中的“ if條件”可以防止使用反射多次實(shí)例化單例。
  • 為了防止從不同的類加載器實(shí)例化單例,可以實(shí)現(xiàn)getClass()方法。 上面的getClass()方法將類加載器與當(dāng)前線程關(guān)聯(lián); 如果該類加載器為null,則該方法使用與加載單例類相同的類加載器。
  • 盡管我們可以使用所有這些技術(shù),但是有一種簡(jiǎn)單的方法可以創(chuàng)建單例類。 從JDK 1.5開始,您可以使用枚舉創(chuàng)建單例類。 枚舉常量是隱式靜態(tài)的和最終的,創(chuàng)建后就無法更改其值。

    package com.javacodegeeks.patterns.singletonpattern;public class SingletoneEnum {public enum SingleEnum{SINGLETON_ENUM;} }

    當(dāng)您嘗試顯式實(shí)例化Enum對(duì)象時(shí),將出現(xiàn)編譯時(shí)錯(cuò)誤。 當(dāng)Enum靜態(tài)加載時(shí),它是線程安全的。 Enum中的clone方法是最終的,可確保枚舉常量永遠(yuǎn)不會(huì)被克隆。 枚舉本質(zhì)上是可序列化的,序列化機(jī)制可確保不會(huì)因反序列化而創(chuàng)建重復(fù)的實(shí)例。 也禁止使用反射實(shí)例化。 這些確保了枚舉實(shí)例不存在超出枚舉常量定義的實(shí)例。

    3.何時(shí)使用Singleton

  • 一個(gè)類必須完全有一個(gè)實(shí)例,并且必須可以從眾所周知的訪問點(diǎn)訪問它。
  • 當(dāng)唯一的實(shí)例可以通過子類擴(kuò)展,并且客戶端應(yīng)該能夠使用擴(kuò)展的實(shí)例而無需修改其代碼。
  • 4.下載源代碼

    這是有關(guān)Singleton Pattern的課程。 您可以在此處下載源代碼: SingletonPattern-Project

    翻譯自: https://www.javacodegeeks.com/2015/09/singleton-design-pattern.html

    總結(jié)

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

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