二維碼
        企資網(wǎng)

        掃一掃關(guān)注

        當(dāng)前位置: 首頁(yè) » 企資快報(bào) » 品牌 » 正文

        單例模式你寫(xiě)對(duì)了嗎?

        放大字體  縮小字體 發(fā)布日期:2023-02-28 19:43:49    作者:馮馨代    瀏覽次數(shù):62
        導(dǎo)讀

        前言我們都知道,單例模式是設(shè)計(jì)模式里最簡(jiǎn)單得模式,無(wú)論是代碼還是模式得理解都是最簡(jiǎn)單得,但是那么簡(jiǎn)單得東西,你真得寫(xiě)對(duì)了么?單例模式單例模式——確保一個(gè)類只有一個(gè)實(shí)例,并提供全局訪問(wèn)點(diǎn)。要點(diǎn):確保程序

        前言

        我們都知道,單例模式是設(shè)計(jì)模式里最簡(jiǎn)單得模式,無(wú)論是代碼還是模式得理解都是最簡(jiǎn)單得,但是那么簡(jiǎn)單得東西,你真得寫(xiě)對(duì)了么?

        單例模式

        單例模式——確保一個(gè)類只有一個(gè)實(shí)例,并提供全局訪問(wèn)點(diǎn)。

        要點(diǎn):

      1. 確保程序中一個(gè)類最多只有一個(gè)實(shí)例。
      2. 提供訪問(wèn)這個(gè)實(shí)例得全局點(diǎn)。

        乍一看,確實(shí)簡(jiǎn)單,也很好理解,看看怎么實(shí)現(xiàn)得,代碼:

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

        說(shuō)明:目得為了演示,大家不需要關(guān)心Redis得內(nèi)容。

        簡(jiǎn)單吧,把構(gòu)造器 private 不讓別人進(jìn)行實(shí)例化,然后提供一個(gè)對(duì)外實(shí)例化得靜態(tài)方法,如果想使用這個(gè)實(shí)例,那就必須通過(guò) getInstance() 方法進(jìn)行獲取具體得實(shí)例,是不是滿足了單例模式得2個(gè)要點(diǎn)?確實(shí)是,但是,有句“古話”說(shuō)得好:程序員要把任何一個(gè)應(yīng)用都當(dāng)成多線程應(yīng)用。

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

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

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

        給 getInstance 加同步鎖

        我們?cè)?getInstance() 方法上加 synchronized 關(guān)鍵字實(shí)現(xiàn)同步鎖,這個(gè)時(shí)候,每個(gè)人進(jìn)入這個(gè)方法前,都需要等待上一個(gè)線程結(jié)束之后,才能進(jìn)入這個(gè)方法,這個(gè)時(shí)候就可以保證最多只有一個(gè)實(shí)例了。代碼:

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

        打完收工~!

        后來(lái),項(xiàng)目越來(lái)越牛B了,自己寫(xiě)得這個(gè)單例越來(lái)越多得地方在使用,然后他們就發(fā)現(xiàn)自己寫(xiě)得代碼怎么越來(lái)越慢,經(jīng)過(guò)排查,就是因?yàn)樽约簩?xiě)得這個(gè)單例引起得,因?yàn)椴还苣愣嗌偃耍愣急仨毾鹊却弦粋€(gè)人拿完了他才能繼續(xù)拿,已經(jīng)驗(yàn)證影響別人得使用了,咋搞?當(dāng)然是優(yōu)化了(誰(shuí)叫甲方是Babababa,哈哈,開(kāi)玩笑)。

        使用 volatile 做雙重檢查

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

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

        在上面得代碼中,synchronized 只會(huì)鎖其中一個(gè)片段,而且因?yàn)関olatile 只會(huì)執(zhí)行一次,所以確保了最多一個(gè)實(shí)例得特性。

        嗯~~ 是不是有點(diǎn)復(fù)雜,有沒(méi)有簡(jiǎn)單點(diǎn)得,有得!有個(gè)更簡(jiǎn)單得,因?yàn)樗焐镁€程安全,以及默認(rèn)得private 得構(gòu)造器,那就是使用枚舉實(shí)現(xiàn)單例模式。

        使用枚舉實(shí)現(xiàn)單例模式(推薦)

        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")); }}

        簡(jiǎn)單吧,但是得從我們正常使用枚舉得思維跳出來(lái)。

        總結(jié)

        程序員應(yīng)該把任何一個(gè)程序都當(dāng)成是多線程。共勉~

      3.  
        (文/馮馨代)
        免責(zé)聲明
        本文僅代表作發(fā)布者:馮馨代個(gè)人觀點(diǎn),本站未對(duì)其內(nèi)容進(jìn)行核實(shí),請(qǐng)讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問(wèn)題,請(qǐng)及時(shí)聯(lián)系我們刪除處理郵件:weilaitui@qq.com。
         

        Copyright ? 2016 - 2025 - 企資網(wǎng) 48903.COM All Rights Reserved 粵公網(wǎng)安備 44030702000589號(hào)

        粵ICP備16078936號(hào)

        微信

        關(guān)注
        微信

        微信二維碼

        WAP二維碼

        客服

        聯(lián)系
        客服

        聯(lián)系客服:

        在線QQ: 303377504

        客服電話: 020-82301567

        E_mail郵箱: weilaitui@qq.com

        微信公眾號(hào): weishitui

        客服001 客服002 客服003

        工作時(shí)間:

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

        反饋

        用戶
        反饋

        主站蜘蛛池模板: 久久AAAA片一区二区| 国产韩国精品一区二区三区久久| 久久一区二区三区精品| 国产精品亚洲专一区二区三区 | 国产微拍精品一区二区| 日本一区二区三区在线观看 | 夜夜精品无码一区二区三区| 精品日韩亚洲AV无码一区二区三区| 亚洲日本一区二区一本一道| 亚洲高清一区二区三区电影 | 日韩av片无码一区二区不卡电影| 久久人妻av一区二区软件| 久久久久人妻精品一区三寸蜜桃| 日本免费一区尤物| 国产Av一区二区精品久久| 丝袜美腿一区二区三区| 亚洲欧美日韩国产精品一区| 无码精品尤物一区二区三区| 天堂资源中文最新版在线一区 | 日韩高清一区二区三区不卡 | 一区二区三区免费看| 国产人妖视频一区在线观看| 国语对白一区二区三区| 亚洲欧美日韩国产精品一区| 麻豆AV无码精品一区二区| 亚洲色偷偷偷网站色偷一区| 日韩亚洲AV无码一区二区不卡 | 国产精品无码一区二区在线 | 亚洲成a人一区二区三区| 国产香蕉一区二区三区在线视频 | 香蕉免费看一区二区三区| 精品人体无码一区二区三区| 相泽亚洲一区中文字幕| 亚洲AV综合色区无码一区爱AV| 国产福利精品一区二区| 亚洲视频在线一区二区三区| 精品无人乱码一区二区三区| 日韩免费无码一区二区视频| 国产精品亚洲产品一区二区三区 | 亚洲国产欧美国产综合一区 | 无码人妻一区二区三区免费视频 |