av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁技術(shù)文章
文章詳情頁

java面試常見模式問題---單例模式

瀏覽:70日期:2022-08-11 08:43:06
目錄1、簡介2、單例模式——懶漢式3、單例模式——餓漢式總結(jié)1、簡介

單例模式使⽤場景

業(yè)務(wù)系統(tǒng)全局只需要⼀個對象實例,⽐如發(fā)號器、 redis 連接對象等。 Spring IOC容器中的 Bean 默認就是單例。 Spring Boot 中的 Controller、Service、Dao 層中通過 @Autowire的依賴注⼊對象默認都是單例的。

單例模式分類

懶漢:就是所謂的懶加載,延遲創(chuàng)建對象,需要用的時候再創(chuàng)建對象。 餓漢:與懶漢相反,提前創(chuàng)建對象。 單例模式實現(xiàn)步驟: 私有化構(gòu)造函數(shù)提供獲取單例的方法。2、單例模式——懶漢式單例模式——懶漢式有以下⼏種實現(xiàn)⽅式:

/** * @Auther: csp1999 * @Date: 2020/11/06/20:36 * @Description: 單例設(shè)計模式-懶漢式 */public class SingletonLazy { // 當需要用到該實例的時候再創(chuàng)建實例對象 private static SingletonLazy instance; /** * 構(gòu)造函數(shù)私有化 * 不能通過 new SingletonLazy() 的方式創(chuàng)建實例 * * 當需要用到該實例的時候在加載 * 只能通過 SingletonLazy.getInstance() 這種方式獲取實例 */ private SingletonLazy() { } /** * 單例對象的方法 */ public void process() {System.out.println('方法實例化成功!'); } /** * 方式一: * <p> * 對外暴露一個方法獲取該類的對象 * <p> * 缺點:線程不安全,多線程下存在安全問題 * * @return */ public static SingletonLazy getInstance() {if (instance == null) {// 實例為null時候才創(chuàng)建 /** * 線程安全問題: * 當某一時刻,兩個或多個線程同時判斷到instance == null成立的時候 * 這些線程同時進入該if判斷內(nèi)部執(zhí)行實例化 * 則會新建出不止一個SingletonLazy實例 */ instance = new SingletonLazy();// 當需要的時候再進行實例化對象}return instance; } /** * 方式二: * 通過加synchronized鎖 保證線程安全 * * 采用synchronized 對方法加鎖有很大的性能開銷 * 因為當getInstance2()內(nèi)部邏輯比較復雜的時候,在高并發(fā)條件下 * 沒獲取到加鎖方法執(zhí)行權(quán)的線程,都得等到這個方法內(nèi)的復雜邏輯執(zhí)行完后才能執(zhí)行,等待浪費時間,效率比較低 * * @return */ public static synchronized SingletonLazy getInstance2() {if (instance == null) {// 實例為null時候才創(chuàng)建 // 方法上加synchronized鎖后可以保證線程安全 instance = new SingletonLazy();// 當需要的時候再進行實例化對象}return instance; } /** * 方式三: * 在getInstance3()方法內(nèi),針對局部需要加鎖的代碼塊加鎖,而不是給整個方法加鎖 * * 也存在缺陷: * @return */ public static SingletonLazy getInstance3() {if (instance == null) {// 實例為null時候才創(chuàng)建 // 局部加鎖后可以保證線程安全,效率較高 // 缺陷:假設(shè)線程A和線程B synchronized (SingletonLazy.class){// 當線程A獲得鎖的執(zhí)行權(quán)的時候B等待 A執(zhí)行new SingletonLazy();實例化// 當A線程執(zhí)行完畢后,B再獲得執(zhí)行權(quán),這時候還是可以實例化該對象instance = new SingletonLazy();// 當需要的時候再進行實例化對象 }}return instance; }}單例模式:懶漢實現(xiàn) + 雙重檢查鎖定 + 內(nèi)存模型

對于上面方式三存在的缺陷,我們可以使用雙重檢查鎖定的方式對其進行改進

/** * 方式三改進版本: * 在getInstance3()方法內(nèi),針對局部需要加鎖的代碼塊加鎖,而不是給整個方法加鎖 * * DCL 雙重檢查鎖定 (Double-Checked-Locking) 在多線程情況下保持高性能 * * 這是否安全? instance = new SingletonLazy(); 并不是原子性操作 * jvm中 instance實例化內(nèi)存模型流程如下: * 1.分配空間給對象 * 2.在空間內(nèi)創(chuàng)建對象 * 3.將對象賦值給instance引用 * * 假如出現(xiàn)如下順序錯亂的情況: * 線程的執(zhí)行順序為:1 -> 3 -> 2, 那么這時候會把值寫回主內(nèi)存 * 則,其他線程就會讀取到instance的最新值,但是這個是不完全的對象 * (指令重排現(xiàn)象) * * @return */public static SingletonLazy getInstance3plus() { if (instance == null) {// 實例為null時候才創(chuàng)建// 局部加鎖后可以保證線程安全,效率較高// 假設(shè)線程A和線程B synchronized (SingletonLazy.class){// 第一重檢查 // 當線程A獲得鎖的執(zhí)行權(quán)的時候B等待 A執(zhí)行new SingletonLazy();實例化 // 當A線程執(zhí)行完畢后,B再獲得執(zhí)行權(quán),這時候再判斷instance == null是否成立 // 如果不成立,B線程無法 實例化SingletonLazy if (instance == null){// 第二重檢查instance = new SingletonLazy();// 當需要的時候再進行實例化對象 }} } return instance;}

再次升級方式三,來解決內(nèi)存模型中的指令重排問題

// 添加volatile 關(guān)鍵字,禁止實例化對象時,內(nèi)存模型中出現(xiàn)指令重排現(xiàn)象private static volatile SingletonLazy instance;/** * 方式三再次升級版本: * 在getInstance3()方法內(nèi),針對局部需要加鎖的代碼塊加鎖,而不是給整個方法加鎖 * * DCL 雙重檢查鎖定 (Double-Checked-Locking) 在多線程情況下保持高性能 * * 解決指令重排問題——禁止指令重排 * @return */public static SingletonLazy getInstance3plusplus() { if (instance == null) {// 實例為null時候才創(chuàng)建// 局部加鎖后可以保證線程安全,效率較高// 假設(shè)線程A和線程Bsynchronized (SingletonLazy.class){// 第一重檢查 // 當線程A獲得鎖的執(zhí)行權(quán)的時候B等待 A執(zhí)行new SingletonLazy();實例化 // 當A線程執(zhí)行完畢后,B再獲得執(zhí)行權(quán),這時候再判斷instance == null是否成立 // 如果不成立,B線程無法 實例化SingletonLazy if (instance == null){// 第二重檢查instance = new SingletonLazy();// 當需要的時候再進行實例化對象 }} } return instance;}

單例模式——懶漢式調(diào)用:

@Testpublic void testSingletonLazy(){ SingletonLazy.getInstance().process();}3、單例模式——餓漢式

/** * @Auther: csp1999 * @Date: 2020/11/06/21:39 * @Description: 單例設(shè)計模式-餓漢式 */public class SingletonHungry { // 當類加載的時候就直接實例化對象 private static SingletonHungry instance = new SingletonHungry(); private SingletonHungry(){} /** * 單例對象的方法 */ public void process() {System.out.println('方法實例化成功!'); } public static SingletonHungry getInstance(){return instance;// 當類加載的時候就直接實例化對象 }}單例模式——餓漢式調(diào)用:

@Testpublic void testSingletonHungry(){ SingletonHungry.getInstance().process();}

餓漢式單例模式,當類加載的時候就直接實例化對象,因此不需要考慮線程安全問題。

優(yōu)點:實現(xiàn)簡單,不需要考慮線程安全問題。 缺點:不管有沒有使用該對象實例,instance對象一直占用著這段內(nèi)存。

懶漢與餓漢式如何選擇?

如果對象內(nèi)存占用不大,且創(chuàng)建不復雜,直接使用餓漢的方式即可。 其他情況均采用懶漢方式(優(yōu)選)。總結(jié)

文章會不定時更新,有時候一天多更新幾篇,如果幫助您復習鞏固了知識點,還請支持一下,后續(xù)會億點點的更新!希望大家多多關(guān)注好吧啦網(wǎng)的其他內(nèi)容!

標簽: Java
相關(guān)文章:
主站蜘蛛池模板: 黄色av网站在线观看 | 欧美日韩精品一区二区三区蜜桃 | 黑人粗黑大躁护士 | 自拍偷拍亚洲欧美 | 精品久久久久久久久久久 | www成人啪啪18| 尤物视频在线免费观看 | 精品国产免费人成在线观看 | 伊人网站 | 精品二三区 | 欧美一区二区黄 | 国产91久久精品一区二区 | 91精品国产综合久久香蕉麻豆 | 高清av在线 | 中文字字幕一区二区三区四区五区 | 欧美video| 欧美日韩一 | 亚洲国产69| 中文字幕亚洲专区 | 日韩视频一区 | 亚洲一区中文字幕 | ww亚洲ww亚在线观看 | 日韩成人在线一区 | 青青草视频网站 | 中文字幕视频三区 | 国产欧美一区二区三区在线看 | 91色综合 | 一级黄色淫片 | 羞羞午夜| 免费久久久 | 国产精品美女久久久久久久久久久 | 国产午夜精品一区二区三区在线观看 | 欧美国产日韩在线观看 | 99成人| 综合五月 | 精品欧美色视频网站在线观看 | 免费在线观看成人 | 中文字幕免费 | 欧美成人精品一区二区男人看 | www.伊人.com | 中文字幕视频一区 |