成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

mikasa / 2171人閱讀

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

前言

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

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


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

使用場(chǎng)景

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

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

代碼分析
public class EZ {

    private static EZ ez = null;

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

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

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

這是典型的懶漢式單例方法,低并發(fā)的情況下不會(huì)出現(xiàn)問(wè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è)對(duì)象,size>1
        System.out.println(ezSet.size());
    }

}

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

public class BetterEz {
    private static BetterEz ez = null;

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

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

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

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

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

public class EZ {

    private static final EZ ez = new EZ();

    private EZ() {
    }

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

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/68041.html

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

    摘要:原文博客地址單例模式系統(tǒng)中被唯一使用,一個(gè)類只有一個(gè)實(shí)例。中的單例模式利用閉包實(shí)現(xiàn)了私有變量?jī)烧呤欠裣嗟热躅愋?,沒(méi)有私有方法,使用者還是可以直接一個(gè),也會(huì)有方法分割線不是單例最簡(jiǎn)單的單例模式,就是對(duì)象。 原文博客地址:https://finget.github.io/2018/11/06/single/ 單例模式 系統(tǒng)中被唯一使用,一個(gè)類只有一個(gè)實(shí)例。實(shí)現(xiàn)方法一般是先判斷實(shí)例是否存在,...

    lk20150415 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

mikasa

|高級(jí)講師

TA的文章

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