2肛炮、創(chuàng)建型設(shè)計模式-單例設(shè)計模式

江湖傳言里的設(shè)計模式-單例設(shè)計模式

簡介:什么是單例設(shè)計模式和應(yīng)用

  • 備注:面試重點考查

  • 單例設(shè)計模式:

    • 這個是最簡單的設(shè)計模式,所以拎出來第一個講, 但事實卻不是轰坊。
    • 單例意思只包含一個對象被稱為單例的特殊類
    • 通過單例模式可以保證系統(tǒng)中铸董,應(yīng)用該模式的類只有一個對象實例
  • 使用場景

    • 業(yè)務(wù)系統(tǒng)全局只需要一個對象實例,比如發(fā)號器肴沫、redis連接對象等
    • Spring IOC容器中的bean默認就是單例
    • spring boot 中的controller粟害、service、dao層中通過@autowire的依賴注入對象默認都是單例的
  • 分類:

    • 懶漢:就是所謂的懶加載颤芬,延遲創(chuàng)建對象
    • 餓漢:與懶漢相反悲幅,提前創(chuàng)建對象
  • 實現(xiàn)步驟

    • 私有化構(gòu)造函數(shù)
    • 提供獲取單例的方法
單例設(shè)計模式

單例模式中的懶漢實現(xiàn)+雙重檢查鎖定+內(nèi)存模型

代碼:

package net.xdclass;

/**
 * @Description 單例設(shè)計模式 - 懶漢實現(xiàn)方式
 * @Author 二當家小D
 * @Remark 
 * @Version 1.0
 **/

public class SingletonLazy {
    private static SingletonLazy instance;

    /**
     * 構(gòu)造函數(shù)私有化
     */
    private SingletonLazy(){}

    /**
     * 單例對象的方法
     */
    public void process(){
        System.out.println("方法調(diào)用成功");
    }

    /**
     * 第一種方式
     * 對外暴露一個方法獲取類的對象
     *
     * 線程不安全,多線程下存在安全問題
     *
     */
    public static SingletonLazy getInstance(){
        if(instance == null){
            instance = new SingletonLazy();
        }
        return instance;
    }


    /**
     * 第二種實現(xiàn)方式
     *  通過加鎖 synchronized 保證單例
     *
     * 采用synchronized 對方法加鎖有很大的性能開銷
     *
     * 解決辦法:鎖粒度不要這么大
     *
     * @return
     */
    public static synchronized SingletonLazy getInstance(){
        if(instance == null){
            instance = new SingletonLazy();
        }
        return instance;
    }


    /**
     * 第三種實現(xiàn)方式 也不可以站蝠,存在重復(fù)建對象
     * @return
     */
    public static  SingletonLazy getInstance(){
        if(instance == null){
            // A汰具、B
            synchronized (SingletonLazy.class){
                instance = new SingletonLazy();
            }
        }
        return instance;
    }

    /**
     * 第四種實現(xiàn)方式
     *
     * DCL 雙重檢查鎖定 (Double-Checked-Locking),在多線程情況下保持高性能
     *
     * 這是否安全,instance = new SingletonLazy(); 并不是原子性操作
     * 1菱魔、分配空間給對象
     * 2留荔、在空間內(nèi)創(chuàng)建對象
     * 3、將對象賦值給引用instance
     *
     * 假如線程 1-》3-》2順序澜倦,會把值寫會主內(nèi)存聚蝶,其他線程就會讀取到instance最新的值,但是這個是不完全的對象
     * (指令重排)
     * @return
     */
    public static  SingletonLazy getInstance(){
        if(instance == null){
            // A藻治、B
            synchronized (SingletonLazy.class){
                if(instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

    /**
     * volatile是Java提供的關(guān)鍵字碘勉,它具有可見性和有序性,
     *
     * 指令重排序是JVM對語句執(zhí)行的優(yōu)化桩卵,只要語句間沒有依賴验靡,那JVM就有權(quán)對語句進行優(yōu)化
     *
     * 禁止了指令重排
     */
    private static volatile SingletonLazy instance;
    public static  SingletonLazy getInstance(){
        //第一重檢查
        if(instance == null){
            // A、B 雏节,鎖定
            synchronized (SingletonLazy.class){
                //第二重檢查
                if(instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

}

主代碼:

public class Main {

    public static void main(String[] args) {
        SingletonLazy.getInstance().process();
    }
}

單例模式中的懶漢實現(xiàn)+雙重檢查鎖定+內(nèi)存模型

餓漢設(shè)計模式:

  • 餓漢方式:提前創(chuàng)建好對象
  • 優(yōu)點:實現(xiàn)簡單胜嗓,沒有多線程同步問題
  • 缺點:不管有沒使用,instance對象一直占著這段內(nèi)存

如何選擇:

  • 如果對象不大钩乍,且創(chuàng)建不復(fù)雜兼蕊,直接用餓漢的方式即可
  • 其他情況則采用懶漢實現(xiàn)方式

代碼:

public class SingletonHungry {
    private static SingletonHungry instance = new SingletonHungry();

    private SingletonHungry(){}

    public static SingletonHungry getInstance(){
        return instance;
    }

    /**
     * 單例對象的方法
     */
    public void process(){
        System.out.println("方法調(diào)用成功");
    }

}

``
Main代碼:

public class Main {
public static void main(String[] args) {
//SingletonLazy.getInstance().process();
SingletonHungry.getInstance().process();
}
}

``

單例設(shè)計模式在JDK源碼里面的應(yīng)用

  • JDK中Runtime類 餓漢方式
JDK中Runtime類 餓漢方式

Runtime類用于表示虛擬機運行時的狀態(tài), 用于封裝JVM虛擬機進程。每次啟動虛擬機都對應(yīng)一個Runtime實例, 且只有一個實例件蚕。因為該類采用單例模式設(shè)計, 對象不可以直接實例化. 所以要想獲得一個Runtime實例, 只能通過如下方式:

Runtime rt = Runtime.getRuntime();

示例代碼:

public static void main(String[] args) {
    // 獲取Runtime實例對象
    Runtime rt = Runtime.getRuntime();
    System.out.println("處理器個數(shù): "+rt.availableProcessors());
    System.out.println("空閑內(nèi)存M數(shù): "+rt.freeMemory()/1024/1024);
    System.out.println("最大可用內(nèi)存M數(shù): "+rt.maxMemory()/1024/1024);
}
  • JDK中Desktop類 懶漢方式
懶漢方式
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孙技,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子排作,更是在濱河造成了極大的恐慌牵啦,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妄痪,死亡現(xiàn)場離奇詭異哈雏,居然都是意外死亡,警方通過查閱死者的電腦和手機衫生,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門裳瘪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人罪针,你說我怎么就攤上這事彭羹。” “怎么了泪酱?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵派殷,是天一觀的道長。 經(jīng)常有香客問我墓阀,道長毡惜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任斯撮,我火速辦了婚禮经伙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘勿锅。我一直安慰自己帕膜,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布粱甫。 她就那樣靜靜地躺著泳叠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茶宵。 梳的紋絲不亂的頭發(fā)上危纫,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音乌庶,去河邊找鬼种蝶。 笑死,一個胖子當著我的面吹牛瞒大,可吹牛的內(nèi)容都是我干的螃征。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼透敌,長吁一口氣:“原來是場噩夢啊……” “哼盯滚!你這毒婦竟也來了踢械?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤魄藕,失蹤者是張志新(化名)和其女友劉穎内列,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體背率,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡话瞧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了寝姿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片交排。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饵筑,靈堂內(nèi)的尸體忽然破棺而出埃篓,到底是詐尸還是另有隱情,我是刑警寧澤翻翩,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布都许,位于F島的核電站,受9級特大地震影響嫂冻,放射性物質(zhì)發(fā)生泄漏胶征。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一桨仿、第九天 我趴在偏房一處隱蔽的房頂上張望睛低。 院中可真熱鬧,春花似錦服傍、人聲如沸钱雷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罩抗。三九已至,卻和暖如春灿椅,著一層夾襖步出監(jiān)牢的瞬間套蒂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工茫蛹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留操刀,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓婴洼,卻偏偏與公主長得像骨坑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子柬采,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容