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

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

生活随笔

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

asp.net

单例设计模式-容器单例

發(fā)布時(shí)間:2024/4/13 asp.net 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单例设计模式-容器单例 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
基于容器的單例模式,與享元模式類似,我們也可以使用容器單例模式,來(lái)管理多個(gè)單例對(duì)象,那我們通過(guò)coding,debug,講解的方式來(lái)學(xué)習(xí)一下 package com.learn.design.pattern.creational.singleton;import org.apache.commons.lang3.StringUtils;import java.util.HashMap; import java.util.Map;/*** 容器的單例類* 那這個(gè)類實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單* 我們來(lái)操作一下* * * * @author Leon.Sun**/ public class ContainerSingleton {/*** 我們沒(méi)有寫(xiě)他的private構(gòu)造器* 這樣我們直接調(diào)用靜態(tài)方法* 這種public的方法* 就OK了* 然來(lái)到Test里面* * */private ContainerSingleton(){}/*** 首先聲明一個(gè)Map* 我們的KEY使用一個(gè)String* value就用Object* 這個(gè)叫singletonMap* new一個(gè)HashMap* 這個(gè)泛型也寫(xiě)上* 那這個(gè)map就寫(xiě)好了* 本身這個(gè)Map作為緩存的話* 要往里放對(duì)象* 也好取對(duì)象* 那很簡(jiǎn)單的* * */private static Map<String,Object> singletonMap = new HashMap<String,Object>();/*** putInstance兩個(gè)參數(shù)* 一個(gè)是key* 另外是instance* 因?yàn)樗且粋€(gè)map* 可以管理很多對(duì)象* 然后做一個(gè)簡(jiǎn)單的判斷* * * @param key* @param instance*/public static void putInstance(String key,Object instance){/*** 用blank來(lái)判斷key* 并且instance不為null* 當(dāng)這種情況下* 我們才會(huì)往里邊放* 那在放之前呢* 我們還要用map來(lái)判斷一下* * Thread0進(jìn)到這里面他開(kāi)始判斷* 判斷肯定正常* key傳的是object* value也是一個(gè)object* 注意它是@420* * */if(StringUtils.isNotBlank(key) && instance != null){/*** singletonMap.containsKey取反* 當(dāng)不包含這個(gè)key的時(shí)候* 我們才會(huì)真正的往里放* put key和instance* 那所謂的容器單例呢* 就是通過(guò)這個(gè)map呢去實(shí)現(xiàn)單例對(duì)象的一個(gè)容器* 那這里是保證key的合法性和唯一性* 那接下來(lái)也很簡(jiǎn)單* * 進(jìn)入到這里肯定是不存在的* 因?yàn)閙ap里面的size還是0* * */if(!singletonMap.containsKey(key)){/*** 這一行先不動(dòng)* 切另一個(gè)線程* 他也會(huì)同樣的進(jìn)來(lái)* 那我們看一下這個(gè)instance* 是449* 另外一個(gè)instance是420* 也就是說(shuō)在放的時(shí)候* 放了兩個(gè)對(duì)象* 但是他們的key是同一個(gè)* 也就是說(shuō)在初始化的時(shí)候* 這個(gè)對(duì)象是有可能放多個(gè)的* 那具體還要看線程的數(shù)量* 但是一旦放置完成呢* 我們?cè)谌〉臅r(shí)候* 就只會(huì)取一個(gè)呢* 因?yàn)楹髨?zhí)行的* 把之前執(zhí)行的* 覆蓋掉* 因?yàn)樗麄兊膋ey一樣的* 那put ok了* Thread0里面放的是420* 我們直接F8過(guò)來(lái)* 剛剛有說(shuō)* Thread0放的是420* 我們打開(kāi)這個(gè)map* 我們可以看到map里面放的是420* 我們?cè)偾谢豑hread1* 執(zhí)行put* 然后F8* Thread1也到getInstance這里呢* 我們看一下map里面的值* 里面已經(jīng)變成449* 也就是說(shuō)后執(zhí)行的Thread1* 將要獲取449這個(gè)Object* 那我們?cè)偾谢豑hread0* 看一下這個(gè)Map* 他已經(jīng)變成449了* 你看上去這里將要返回同一個(gè)對(duì)象* 但是有一點(diǎn)* 我們現(xiàn)在在干預(yù)線程* 如果不干預(yù)線程的話* 例如Thread0先放置成功* 他就立刻返回了* Thread1才去放置* Thead1返回* 那這樣的話他們返回的對(duì)象就不是同一個(gè)了* 我們把斷點(diǎn)取消* 直接F8過(guò)* 從結(jié)果看上Thread0和Thread1返回的都是同一個(gè)對(duì)象* 但是他們中間還是有隱患的* 所以這種單例模式適用場(chǎng)景之前也說(shuō)了* 根據(jù)實(shí)際的業(yè)務(wù)需要* 我們?cè)倏匆幌逻@個(gè)類* 我們想一下* HashMap他本身就不是線程安全的* 那如果我們把它改成Hashtable的話* 會(huì)不會(huì)就變成線程安全呢* 當(dāng)然Hashtable是線程安全的* 我們?nèi)绻褂肏ashtable的話* 這種模式的單例模式就是線程安全的* 但是我們頻繁去取的時(shí)候* 建議使用同步鎖* 不建議使用Hashtable* 那我們可以折中一下* 但是我們使用了靜態(tài)的HashMap* 而且直接操作了這個(gè)map* 那在這種場(chǎng)景下呢* ConCurrentHashMap并不是絕對(duì)的線程安全* 所以我們不考慮安全機(jī)制的話* 這種容器單例模式* 也是有一定適用場(chǎng)景的* 在安卓的SDK也用的比較多* JDK中也有這種模式* 那后邊我們會(huì)講解一些單例模式在源碼中的應(yīng)用* JDK中使用容器解決單例模式的一個(gè)方案* 和這個(gè)比較類似* 所以在使用這種模式的時(shí)候* 我建議它使用Hashtable* 所以呢這種單例模式* 是一個(gè)平衡* 根據(jù)業(yè)務(wù)場(chǎng)景來(lái)判斷* 如果我們系統(tǒng)中單例模式非常多的話* 我們也可以考慮用一個(gè)容器把單例* 他的優(yōu)點(diǎn)是統(tǒng)一管理* map相當(dāng)于一個(gè)緩存* 確認(rèn)是線程不安全* * * */singletonMap.put(key,instance);}}}/*** 參數(shù)是key* * * @param key* @return*/public static Object getInstance(String key){/*** 從singletonMap直接get key就可以了* 非常簡(jiǎn)單* 這種寫(xiě)法非常時(shí)候容器在初始化的時(shí)候* 我們就把多個(gè)單例對(duì)象放入到singletonMap里邊* 統(tǒng)一管理* 那在使用的時(shí)候呢* 通過(guò)key直接從map當(dāng)中獲取單例對(duì)象* 那這里面我們也聯(lián)想一下* 假設(shè)我們認(rèn)為singletonMap是一個(gè)容器的話* 對(duì)于Spring容器* Spring容器里講的單例和我們現(xiàn)在講的單例* 是沒(méi)有關(guān)系的* 但是可以類比一下* 我們從Spring容器里面取對(duì)象的時(shí)候* 默認(rèn)如果不配置的話* 是一個(gè)單例的* 那如果我們?cè)陬惿霞由献⒔? 或者配置bean的屬性為prototype屬性的話* 那他就變成一個(gè)多例的* 但對(duì)于這一塊我們先不深入講解* 那我們先回來(lái)接著說(shuō)這個(gè)* 那我們看一下* 這里面我們使用HashMap* 很明顯的* 如果用HashMap肯定不是線程安全的* 但是如果我們使用他* 在類初始化的時(shí)候* 去把這個(gè)map初始化完成* 也就是把所有的單例對(duì)象都生成完* 放到這里邊* 用的時(shí)候直接用* 這樣是可以的* 所以這種單例模式* 還是要看具體的業(yè)務(wù)場(chǎng)景* 那我們簡(jiǎn)單測(cè)試一下* 還是用多線程debug來(lái)看一下* 這種模式單例模式實(shí)現(xiàn)方案安全問(wèn)題* 首先我們打開(kāi)Test這個(gè)類* Test類比較多* 我們看Singleton里面的* * * */return singletonMap.get(key);} } package com.learn.design.pattern.creational.singleton;public class T implements Runnable {@Overridepublic void run() { // LazySingleton lazySingleton = LazySingleton.getInstance(); // System.out.println(Thread.currentThread().getName()+" "+lazySingleton); // LazyDoubleCheckSingleton instance = LazyDoubleCheckSingleton.getInstance(); // StaticInnerClassSingleton instance = StaticInnerClassSingleton.getInstance();;ContainerSingleton.putInstance("object",new Object());/*** 從這里面取一下instance* 以為這里調(diào)用的是靜態(tài)方法* 所以呢* 回到這個(gè)類里面* * */Object instance = ContainerSingleton.getInstance("object"); // ThreadLocalInstance instance = ThreadLocalInstance.getInstance();System.out.println(Thread.currentThread().getName()+" "+instance);} } package com.learn.design.pattern.creational.singleton;import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { // LazySingleton lazySingleton = LazySingleton.getInstance();// System.out.println("main thread"+ThreadLocalInstance.getInstance()); // System.out.println("main thread"+ThreadLocalInstance.getInstance()); // System.out.println("main thread"+ThreadLocalInstance.getInstance()); // System.out.println("main thread"+ThreadLocalInstance.getInstance()); // System.out.println("main thread"+ThreadLocalInstance.getInstance()); // System.out.println("main thread"+ThreadLocalInstance.getInstance());/*** 現(xiàn)在是兩個(gè)線程* 我們把往容器放對(duì)象的這個(gè)過(guò)程* 放到線程里邊* 讓他們并發(fā)去放* 來(lái)到T里邊* * */Thread t1 = new Thread(new T());Thread t2 = new Thread(new T());t1.start();t2.start();System.out.println("program end");// HungrySingleton instance = HungrySingleton.getInstance(); // EnumInstance instance = EnumInstance.getInstance(); // instance.setData(new Object());// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file")); // oos.writeObject(instance);// File file = new File("singleton_file"); // ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));// HungrySingleton newInstance = (HungrySingleton) ois.readObject(); // EnumInstance newInstance = (EnumInstance) ois.readObject();// System.out.println(instance.getData()); // System.out.println(newInstance.getData()); // System.out.println(instance.getData() == newInstance.getData());// Class objectClass = HungrySingleton.class; // Class objectClass = StaticInnerClassSingleton.class;// Class objectClass = LazySingleton.class; // Class objectClass = EnumInstance.class;// Constructor constructor = objectClass.getDeclaredConstructor(); // Constructor constructor = objectClass.getDeclaredConstructor(String.class,int.class); // // constructor.setAccessible(true); // EnumInstance instance = (EnumInstance) constructor.newInstance(); // EnumInstance instance = (EnumInstance) constructor.newInstance("Geely",666);// // LazySingleton newInstance = (LazySingleton) constructor.newInstance(); // LazySingleton instance = LazySingleton.getInstance();// StaticInnerClassSingleton instance = StaticInnerClassSingleton.getInstance(); // StaticInnerClassSingleton newInstance = (StaticInnerClassSingleton) constructor.newInstance();// HungrySingleton newInstance = (HungrySingleton) constructor.newInstance(); // HungrySingleton instance = HungrySingleton.getInstance();// System.out.println(instance); // System.out.println(newInstance);// System.out.println(instance == newInstance);// EnumInstance instance = EnumInstance.getInstance(); // instance.printTest();} }

?

超強(qiáng)干貨來(lái)襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

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

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