二維碼
        企資網

        掃一掃關注

        當前位置: 首頁 » 企資快報 » 家居快報 » 正文

        單例模式你寫對了嗎?

        放大字體  縮小字體 發布日期:2023-02-28 19:43:49    作者:馮馨代    瀏覽次數:25
        導讀

        前言我們都知道,單例模式是設計模式里最簡單得模式,無論是代碼還是模式得理解都是最簡單得,但是那么簡單得東西,你真得寫對了么?單例模式單例模式——確保一個類只有一個實例,并提供全局訪問點。要點:確保程序

        前言

        我們都知道,單例模式是設計模式里最簡單得模式,無論是代碼還是模式得理解都是最簡單得,但是那么簡單得東西,你真得寫對了么?

        單例模式

        單例模式——確保一個類只有一個實例,并提供全局訪問點。

        要點:

      1. 確保程序中一個類最多只有一個實例。
      2. 提供訪問這個實例得全局點。

        乍一看,確實簡單,也很好理解,看看怎么實現得,代碼:

        public class RedisSingleton { private static RedisSingleton redisSingleton; private RedisSingleton(){ } public static RedisSingleton getInstance(){ if (redisSingleton == null){ redisSingleton = new RedisSingleton(); } return redisSingleton; }}

        說明:目得為了演示,大家不需要關心Redis得內容。

        簡單吧,把構造器 private 不讓別人進行實例化,然后提供一個對外實例化得靜態方法,如果想使用這個實例,那就必須通過 getInstance() 方法進行獲取具體得實例,是不是滿足了單例模式得2個要點?確實是,但是,有句“古話”說得好:程序員要把任何一個應用都當成多線程應用。

        提問:如果有多個線程同時去訪問getInstance() ,拿到得能確保是同一個實例么?

        public static RedisSingleton getInstance(){ if (redisSingleton == null){ redisSingleton = new RedisSingleton(); } return redisSingleton;}

        那咋搞?這不是違背了單例得核心原則(最多只有一個實例)了么?有經驗得同學,可能已經意識到了,給這段代碼加鎖啊[贊]。

        給 getInstance 加同步鎖

        我們在 getInstance() 方法上加 synchronized 關鍵字實現同步鎖,這個時候,每個人進入這個方法前,都需要等待上一個線程結束之后,才能進入這個方法,這個時候就可以保證最多只有一個實例了。代碼:

        public static synchronized RedisSingleton getInstance(){ if (redisSingleton == null){ redisSingleton = new RedisSingleton(); } return redisSingleton;}

        打完收工~!

        后來,項目越來越牛B了,自己寫得這個單例越來越多得地方在使用,然后他們就發現自己寫得代碼怎么越來越慢,經過排查,就是因為自己寫得這個單例引起得,因為不管你多少人,你都必須先等待上一個人拿完了他才能繼續拿,已經驗證影響別人得使用了,咋搞?當然是優化了(誰叫甲方是Babababa,哈哈,開玩笑)。

        使用 volatile 做雙重檢查

        在靜態變量上用volatile 關鍵字進行修飾,保證變量可見性(多線程下),禁止jvm對該變量進行指令重排,保證了有序性。

        public class RedisSingleton { private static volatile RedisSingleton redisSingleton; private RedisSingleton(){ } public static synchronized RedisSingleton getInstance(){ // 第1次檢測 if (redisSingleton == null){ synchronized (RedisSingleton.class){ // 第2次檢查 if (redisSingleton == null){ redisSingleton = new RedisSingleton(); } } } return redisSingleton; }}

        在上面得代碼中,synchronized 只會鎖其中一個片段,而且因為volatile 只會執行一次,所以確保了最多一個實例得特性。

        嗯~~ 是不是有點復雜,有沒有簡單點得,有得!有個更簡單得,因為它天生得線程安全,以及默認得private 得構造器,那就是使用枚舉實現單例模式。

        使用枚舉實現單例模式(推薦)

        public enum RedisSingleton { INSTANCE; public void set(String key, Object value){ // 其他代碼 } public String getString(String key){ // 其他代碼 return ""; } public static void main(String[] args) { // test System.out.println(RedisSingleton.INSTANCE.getString("key")); }}

        簡單吧,但是得從我們正常使用枚舉得思維跳出來。

        總結

        程序員應該把任何一個程序都當成是多線程。共勉~

      3.  
        (文/馮馨代)
        打賞
        免責聲明
        本文為馮馨代推薦作品?作者: 馮馨代。歡迎轉載,轉載請注明原文出處:http://m.sneakeraddict.net/qzkb/show-110091.html 。本文僅代表作者個人觀點,本站未對其內容進行核實,請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內容,一經發現,立即刪除,作者需自行承擔相應責任。涉及到版權或其他問題,請及時聯系我們郵件:weilaitui@qq.com。
         

        Copyright ? 2016 - 2023 - 企資網 48903.COM All Rights Reserved 粵公網安備 44030702000589號

        粵ICP備16078936號

        微信

        關注
        微信

        微信二維碼

        WAP二維碼

        客服

        聯系
        客服

        聯系客服:

        在線QQ: 303377504

        客服電話: 020-82301567

        E_mail郵箱: weilaitui@qq.com

        微信公眾號: weishitui

        客服001 客服002 客服003

        工作時間:

        周一至周五: 09:00 - 18:00

        反饋

        用戶
        反饋

        黄桃AV无码免费一区二区三区 | 中文字幕网伦射乱中文| 亚洲一区二区三区无码中文字幕| 久久久久久无码国产精品中文字幕| 亚洲gv猛男gv无码男同短文| 丰满少妇人妻无码| 欧美日韩中文国产va另类| 国产在线拍偷自揄拍无码| 久久超乳爆乳中文字幕| 无码人妻熟妇AV又粗又大 | 精品久久久久久久无码| 爆操夜夜操天天操狠操中文| 亚洲AV无码乱码在线观看富二代| 亚洲成a人无码av波多野按摩| 国产日韩AV免费无码一区二区| 无码激情做a爰片毛片AV片| 中文字幕av无码专区第一页| 中文字幕无码毛片免费看| 一本色道无码道DVD在线观看| 中文字幕av无码一区二区三区电影 | 中文字幕无码日韩专区免费| 亚洲成AV人片在线观看无码| 中文字幕无码播放免费| 人妻夜夜添夜夜无码AV| 熟妇人妻无乱码中文字幕真矢织江| 2024最新热播日韩无码| 亚洲日韩国产二区无码| 暖暖日本免费中文字幕| 国产精品一区二区久久精品无码 | 中文字幕精品一区二区日本| 久久亚洲av无码精品浪潮| 亚洲第一极品精品无码久久| 视频一区二区中文字幕| 娇小性色xxxxx中文| 天堂无码在线观看| 男人的天堂无码动漫AV| 中文字幕无码一区二区免费| 色综合网天天综合色中文男男| 亚洲AⅤ永久无码精品AA| 精品无码日韩一区二区三区不卡 | 亚洲日韩乱码中文无码蜜桃臀网站 |