成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

設(shè)計(jì)模式之單例模式

mikasa / 2109人閱讀

摘要:代碼分析構(gòu)造函數(shù)私有化,防止外部直接調(diào)用構(gòu)造函數(shù)通過改靜態(tài)方法獲取單例對象這是典型的懶漢式單例方法,低并發(fā)的情況下不會出現(xiàn)問題,若系統(tǒng)壓力增大,并發(fā)量增加將有非常大的可能創(chuàng)建多個(gè)實(shí)例。

前言

終于到周末了,又玩起了最愛的lol,最近新版本出了一個(gè)特別的天賦--偷錢(具體名字想不起來了),配上ez簡直是吊炸天,我玩的單排,僅用了不到三十分鐘就殺的對面出不了家,正當(dāng)我看著傷害板沾沾自喜,對面ad說不就是選了個(gè)版本最強(qiáng)ad,有什么了不起的...本帥這種具有理想抱負(fù)的屌絲當(dāng)然不會和這群傻叉多說什么,關(guān)閉了游戲,就來寫這篇文章,構(gòu)思的過程中想到,lol單排不能選重復(fù)英雄的機(jī)制不就是今天要講的單例模式嗎!

什么是單例模式
確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。
單例模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1. 既然是單例模式,就說明內(nèi)存中只存在一個(gè)實(shí)例,當(dāng)一個(gè)對象需要頻繁創(chuàng)建銷毀時(shí),而創(chuàng)建銷毀對象是虛擬機(jī)控制的,我們無法直接優(yōu)化其性能,單例模式的優(yōu)勢的就會體現(xiàn)的很明顯。


缺點(diǎn):
1.單例模式一般是沒有接口的,因?yàn)樗荒J(rèn)要求自行實(shí)例化。
2.單例模式對測試也是不利的,在并行開發(fā)環(huán)境下,假如我們的單例代碼還沒有開發(fā)好,沒有接口也不能通過mock的方式虛擬一個(gè)對象。
3.單例模式和上節(jié)講的單一原則有點(diǎn)沖突,因?yàn)閱卫O(shè)計(jì)模式把必須單例當(dāng)作一種業(yè)務(wù)和其他業(yè)務(wù)邏輯融入到一個(gè)類中。

使用場景

對象是無狀態(tài)的,也就是說一個(gè)對象和多個(gè)對象辦的事都是一樣的,這樣的話,我們就有必要減少內(nèi)存使用和gc的消耗。

當(dāng)創(chuàng)建一個(gè)對象消耗的資源過于昂貴,比如通過io流讀寫文件、連接數(shù)據(jù)庫等資源。

代碼分析
public class EZ {

    private static EZ ez = null;

    //構(gòu)造函數(shù)私有化,防止外部直接調(diào)用構(gòu)造函數(shù)
    private EZ() {
    }

    //通過改靜態(tài)方法獲取單例對象
    public static EZ getSingletonEz() {

        if (ez == null) {
            return new EZ();
        }
        return ez;
    }
}

這是典型的懶漢式單例方法,低并發(fā)的情況下不會出現(xiàn)問題,若系統(tǒng)壓力增大,并發(fā)量增加將有非常大的可能創(chuàng)建多個(gè)實(shí)例。我們可以自己創(chuàng)建線程池,自己偽造一個(gè)并發(fā)環(huán)境,代碼如下:

public class SingletonTest {
    private  static ExecutorService executorService = Executors.newFixedThreadPool(1000);

    public static void main(String[] args) throws InterruptedException {
        //給系統(tǒng)足夠的時(shí)候啟動(dòng)1000個(gè)線程
        Thread.sleep(5000);
        final Set ezSet = new HashSet<>();
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                ezSet.add(EZ.getSingletonEz().toString());
            }
        });
        Thread.sleep(5000);
        //若創(chuàng)建多個(gè)對象,size>1
        System.out.println(ezSet.size());
    }

}

這個(gè)例子在公司的時(shí)候有測試過,大概運(yùn)行七八次就可以重現(xiàn)一次創(chuàng)建多個(gè)對象的現(xiàn)象。無奈現(xiàn)在家中,電腦配置過高,試了20次,竟一次都沒有重現(xiàn)。哎~。~,配置高有時(shí)也挺不方便的,你們電腦不好的可以試下?_?;既然存在并發(fā)情況創(chuàng)建多個(gè)對象問題,那我們就有必要改善下:

public class BetterEz {
    private static BetterEz ez = null;

    //構(gòu)造函數(shù)私有化,防止外部直接調(diào)用構(gòu)造函數(shù)
    private BetterEz() {
    }

    //通過改靜態(tài)方法獲取單例對象
    public static BetterEz getSingletonEz() {

        if (ez == null) {
            synchronized (BetterEz.class) {
                if (ez == null)
                    return new BetterEz();
            }
        }
        return ez;
    }

}
我們通過synchronized控制同一時(shí)間只有一個(gè)請求可以訪問同步代碼塊,但為什么又要在內(nèi)部加一層判斷呢?假如線程A、B同時(shí)請求,A獲得鎖執(zhí)行,B等待。當(dāng)A執(zhí)行完,B獲得鎖再去執(zhí)行,若沒有這個(gè)判斷豈不又重新創(chuàng)建了新對象。但這種典型的double-check的懶漢單例存在了一個(gè)可能發(fā)生的問題, jvm接收到new指令時(shí),簡單分為3步(實(shí)際更多,可參考深入理解虛擬機(jī)),1分配內(nèi)存2實(shí)例化對象3將內(nèi)存地址指向引用。java的內(nèi)存模型并不限制指令的重排序,也就說當(dāng)執(zhí)行步驟從1-》2-》3變成1-》3-》2。當(dāng)線程a訪問走到第2步,未完成實(shí)例化對象前,線程b訪問此對象的返回一個(gè)引用,但若是進(jìn)行其他操作,因?yàn)閷ο蟛]有實(shí)例化,會造成this逃逸的問題。jdk1.5之后對violate進(jìn)行了重新解釋,使用violate會強(qiáng)制保證線程可見性,增加內(nèi)存屏障,禁止指令優(yōu)化,從而避免這個(gè)問題?;蛘卟捎灭I漢式創(chuàng)建對象。

上面說的都是懶漢式單例,還有一種是餓漢式單例。懶漢式的優(yōu)點(diǎn)在于當(dāng)一次食用才會new對象,餓漢式的優(yōu)點(diǎn)在于在第一次獲取該對象的效率更高。下面我們看一下餓漢式單例:

public class EZ {

    private static final EZ ez = new EZ();

    private EZ() {
    }

    public static EZ getSingletonEz() {
        return ez;
    }
}

當(dāng)類第一次初始化的時(shí)候,就會對靜態(tài)域賦值。而jvm對于類的初始化進(jìn)行了嚴(yán)格規(guī)定,有且只有5種情況必須對類進(jìn)行初始化,關(guān)于類加載的問題不屬于這篇博客的范疇,就不多說了我們只需理解為這是靜態(tài)變量只會初始化一次,并且這是虛擬機(jī)保證的即可。

以上就是我對單例模式的理解,感謝各位的收看

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68041.html

相關(guān)文章

  • 大話PHP設(shè)計(jì)模式單例模式升級版

    摘要:用來指向已創(chuàng)建好的實(shí)例構(gòu)造函數(shù)為空注意這里是關(guān)鍵這是我們需要調(diào)用的方法把函數(shù)也定義為空,這樣就大功告成啦。 接上一篇大話PHP設(shè)計(jì)模式之單例模式 這一篇介紹一下升級版的單例模式,廢話不說先上代碼 不完美的單例模式 class singleMode { //用來指向已創(chuàng)建好的實(shí)例 public static $instance; //判斷是...

    darcrand 評論0 收藏0
  • 每天一個(gè)設(shè)計(jì)模式單例模式

    摘要:博主按每天一個(gè)設(shè)計(jì)模式旨在初步領(lǐng)會設(shè)計(jì)模式的精髓,目前采用靠這吃飯和純粹喜歡兩種語言實(shí)現(xiàn)。單例模式用途如果一個(gè)類負(fù)責(zé)連接數(shù)據(jù)庫的線程池日志記錄邏輯等等,此時(shí)需要單例模式來保證對象不被重復(fù)創(chuàng)建,以達(dá)到降低開銷的目的。 博主按:《每天一個(gè)設(shè)計(jì)模式》旨在初步領(lǐng)會設(shè)計(jì)模式的精髓,目前采用javascript(_靠這吃飯_)和python(_純粹喜歡_)兩種語言實(shí)現(xiàn)。誠然,每種設(shè)計(jì)模式都有多種實(shí)...

    yy736044583 評論0 收藏0
  • 每天一個(gè)設(shè)計(jì)模式單例模式

    摘要:博主按每天一個(gè)設(shè)計(jì)模式旨在初步領(lǐng)會設(shè)計(jì)模式的精髓,目前采用靠這吃飯和純粹喜歡兩種語言實(shí)現(xiàn)。單例模式用途如果一個(gè)類負(fù)責(zé)連接數(shù)據(jù)庫的線程池日志記錄邏輯等等,此時(shí)需要單例模式來保證對象不被重復(fù)創(chuàng)建,以達(dá)到降低開銷的目的。 博主按:《每天一個(gè)設(shè)計(jì)模式》旨在初步領(lǐng)會設(shè)計(jì)模式的精髓,目前采用javascript(_靠這吃飯_)和python(_純粹喜歡_)兩種語言實(shí)現(xiàn)。誠然,每種設(shè)計(jì)模式都有多種實(shí)...

    lijy91 評論0 收藏0
  • 大話PHP設(shè)計(jì)模式單例模式

    摘要:上面是簡單的單例模式,自己寫程序的話夠用了,如果想繼續(xù)延伸,請傳送至大話設(shè)計(jì)模式之單例模式升級版 看了那么多單例的介紹,都是上來就說怎么做,也沒見說為什么這么做的。那小的就來說說為什么會有單例這個(gè)模式以便更好的幫助初學(xué)者真正的理解這個(gè)設(shè)計(jì)模式,如果你是大神,也不妨看完指正一下O(∩_∩)O首先我不得不吐槽一下這個(gè)模式名字單例,初學(xué)者通過字面很難理解什么是單例,我覺得應(yīng)該叫唯一模式更貼切...

    VEIGHTZ 評論0 收藏0
  • 優(yōu)才公開課筆記:php設(shè)計(jì)模式(一) 單例模式

    摘要:最近開展了三次設(shè)計(jì)模式的公開課,現(xiàn)在來總結(jié)一下設(shè)計(jì)模式在中的應(yīng)用,這是第一篇?jiǎng)?chuàng)建型模式之單例模式。不過因?yàn)椴恢С侄嗑€程所以不需要考慮這個(gè)問題了。 最近開展了三次設(shè)計(jì)模式的公開課,現(xiàn)在來總結(jié)一下設(shè)計(jì)模式在PHP中的應(yīng)用,這是第一篇?jiǎng)?chuàng)建型模式之單例模式。 一、設(shè)計(jì)模式簡介 首先我們來認(rèn)識一下什么是設(shè)計(jì)模式: 設(shè)計(jì)模式是一套被反復(fù)使用、容易被他人理解的、可靠的代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。 設(shè)計(jì)模式不...

    guyan0319 評論0 收藏0
  • JavaScript設(shè)計(jì)模式單例模式

    摘要:原文博客地址單例模式系統(tǒng)中被唯一使用,一個(gè)類只有一個(gè)實(shí)例。中的單例模式利用閉包實(shí)現(xiàn)了私有變量兩者是否相等弱類型,沒有私有方法,使用者還是可以直接一個(gè),也會有方法分割線不是單例最簡單的單例模式,就是對象。 原文博客地址:https://finget.github.io/2018/11/06/single/ 單例模式 系統(tǒng)中被唯一使用,一個(gè)類只有一個(gè)實(shí)例。實(shí)現(xiàn)方法一般是先判斷實(shí)例是否存在,...

    lk20150415 評論0 收藏0

發(fā)表評論

0條評論

mikasa

|高級講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<