黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 單例設(shè)計(jì)模式的幾種實(shí)現(xiàn)方式

單例設(shè)計(jì)模式的幾種實(shí)現(xiàn)方式

更新時(shí)間:2021-08-10 13:33:53 來源:動力節(jié)點(diǎn) 瀏覽1227次

大家對于java語言已經(jīng)不陌生,單例對于java來說也是必不可少的,單例帶來了兩大好處:

1.由于new操作的次數(shù)減少,因而對系統(tǒng)內(nèi)存的使用頻率也會降低,這將減輕GC壓力,縮短GC停頓時(shí)間。

2.對于頻繁使用的對象,可以省略創(chuàng)建對象所花費(fèi)的時(shí)間,這對于那些重量級的對象而言,是非常可觀的一筆系統(tǒng)開銷。

所以對于系統(tǒng)的關(guān)鍵組件和被頻繁操作的對象,使用單例模式便可以有效地改善系統(tǒng)性能。

單例的參與者非常簡單,只有單例類和使用者兩個(gè);

下面介紹單例設(shè)計(jì)模式在java代碼的具體實(shí)現(xiàn):

單例模式的核心在于通過一個(gè)接口返回唯一的對象實(shí)例,一個(gè)簡單的單例實(shí)現(xiàn)如下:

public class Singleton {
    private  Singleton() {
        System.out.println("Singleton  is  create"); // 創(chuàng)建單例的過程可能會比較慢
    }
    private static Singleton instance = new Singleton();
    private static Singleton getInstance() {
        return instance;
    }
}

注意代碼的藍(lán)色部分,首先單例類必須要有一個(gè)private訪問級別的構(gòu)造函數(shù),只有這樣,才能確保單例不會在系統(tǒng)中的其他代碼內(nèi)被實(shí)例化,這點(diǎn)是相當(dāng)重要的;其次,instance成員和getInstance()方法必須是static的。

這種單例的實(shí)現(xiàn)方式非常簡單,而且十分可靠,它唯一的不足僅是無法對instance實(shí)例做延遲加載,假如單例的創(chuàng)建過程很慢,而由于instance成員變量是static定義的,因此在JVM加載單例類時(shí),單例對象就會被建立,如果此時(shí),這個(gè)單例類在系統(tǒng)中還扮演其他角色,那么在任何使用這個(gè)單例類的地方都會初始化這個(gè)單例變量,根本就不會管是否被用到。比如單例String工廠,用于創(chuàng)建一些字符串(該類既用于創(chuàng)建單例Singleton,又用于創(chuàng)建String對象)。

public class Singleton {
    private Singleton() {
        System.out.println("Singleton  is  create"); // 創(chuàng)建單例的過程可能會比較慢
    } 
    private static Singleton instance = new Singleton(); 
    private static Singleton getInstance() {
        return instance;
    }     
    public static void CreateString(){       //這是模擬單例類扮演其他角色
        System.out.println("createString in Singleton");
    }
}

上面代碼的意思就是,假如單例類里面有g(shù)etInstance以外的其它靜態(tài)方法,跟單例沒啥關(guān)系的方法,如果使用了Singleton.CreateString()這種調(diào)用,就會自動創(chuàng)建Singleton這個(gè)類實(shí)例(雖然private構(gòu)造已經(jīng)防止了你人為去new這個(gè)單例),這是開發(fā)人員不愿看到的,我運(yùn)行下面代碼(此代碼調(diào)用了上面代碼的createString()方法)進(jìn)行展示:

那么在這個(gè)單例基礎(chǔ)上進(jìn)行延遲加載改良:

public class Singleton {
    private Singleton() {
        System.out.println("LazySingleton  is  create"); // 創(chuàng)建單例的過程可能會比較慢
    }
    private static Singleton instance = null;
    public static synchronized Singleton getInstance() {
        if (instance == null)
            instance = new Singleton();
        return instance;
    }
}

此時(shí)再調(diào)用同樣的測試方法:

解決了這個(gè)問題。

顯而易見,這次改良主要是從JVM加載類的原理上進(jìn)行改良的,上面的代碼在初始化類的時(shí)候給instance賦予null,確保系統(tǒng)啟動的時(shí)候沒有額外的負(fù)載,其次,在getInstance方法中加入判斷單例是否存在,不存在才new。但是getInstance()方法必須是同步的,

否則多線程環(huán)境下,可能線程1正在創(chuàng)建單例時(shí),線程2判斷單例instance為空,就會創(chuàng)建多個(gè)實(shí)例。

但是上面的寫法,存在性能問題,在多線程下,它的耗時(shí)遠(yuǎn)遠(yuǎn)大于第一種單例。以下代碼就說明了此問題:

@Override
        public void run(){
            for (int i = 0; i < 100000; i++)
                Singleton.getInstance();
                System.out.println("spend:" (System.currentTimeMillis()-begintime));
        }

開啟五個(gè)線程同時(shí)完成以上代碼的運(yùn)行,使用第一種單例耗時(shí)0ms,而使用第二種單例耗時(shí)390ms,性能至少相差兩個(gè)數(shù)量級。

為了線程安全使用了同步關(guān)鍵字反而降低了系統(tǒng)性能,為了解決這個(gè)問題,繼續(xù)改進(jìn):

public class Singleton {
    private Singleton() {
        System.out.println("LazySingleton  is  create"); // 創(chuàng)建單例的過程可能會比較慢
    }
    public static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }
    public static synchronized Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

沒錯(cuò),這就是現(xiàn)在最完整的單例寫法,內(nèi)部類實(shí)現(xiàn)單例,除了effctive java中闡述的枚舉單例實(shí)現(xiàn),這種方法是目前最好的實(shí)現(xiàn)方式。

在這個(gè)實(shí)現(xiàn)中,用內(nèi)部類來保護(hù)單例,當(dāng)Singleton類被加載時(shí),內(nèi)部類不會被初始化,所以可以確保Singleton類被載入JVM時(shí),不會初始化單例類,當(dāng)getInstance方法被調(diào)用時(shí),才會加載SingleHolder,從而初始化instance,同時(shí),由于實(shí)例的建立是在類加載時(shí)完成的,故天生對多線程友好,getInstance()方法也不需要使用synchronized修飾,因此,這種實(shí)現(xiàn)能兼顧前兩種寫法的優(yōu)點(diǎn)(延遲加載,非同步)。

最后,在極端情況下,序列化和反序列化可能會破壞單例,一般來說不多見,如果存在就要多加注意,此時(shí)可以加入以下代碼:

private Object readResolve() {
        return instance;
    }

以上就是動力節(jié)點(diǎn)小編介紹的"單例設(shè)計(jì)模式的幾種實(shí)現(xiàn)方式",希望對大家有幫助,想了解更多可查看Java設(shè)計(jì)模式。動力節(jié)點(diǎn)在線學(xué)習(xí)教程,針對沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識,讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。

提交申請后,顧問老師會電話與您溝通安排學(xué)習(xí)

免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 成人免费手机在线看网站 | 亚洲欧美一区二区三区在线 | 国产成人精品亚洲一区 | 麻豆精品在线 | 国产成人综合一区精品 | 成人小视频免费观看 | 亚洲一区二区三区四 | 国产高清不卡视频在线播放 | 亚洲色图在线观看视频 | 曰鲁夜鲁鲁狠狠综合 | 成人黄色小视频在线观看 | 久久久网站亚洲第一 | 亚洲成色999久久网站 | 视频国产精品丝袜第一页 | 欧美性猛交ⅹxxx乱大交免费 | 在线免费观看污网站 | 永久黄网站色视频免费观看99 | 日日摸日日操 | 欧美性xxx极品hd高清 | 久久国产首页 | 一级片一级毛片 | 特一级黄色大片 | 亚洲精品视频专区 | 欧美日韩视频一区二区在线观看 | 国产精品日韩 | 美女视频黄频免费大全软件 | 99re热视频这里只有精品5 | 欧美日本一二三区 | 亚洲精品中文字幕乱码无线 | 亚洲精品xxx | 男女上下猛烈动态图午夜 | 日批软件在线观看 | 国产欧美成人免费观看视频 | 欧美一级视频免费观看 | 天天综合天天综合 | 成人久久伊人精品伊人 | 福利三级| 天天草狠狠干 | 老司机深夜影院入口aaaa | 又黄又www| 午夜三级影院 |