免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

實現singleton的四種方法-創新互聯

這篇文章主要為大家詳細介紹了實現singleton的四種方法,文中示例代碼介紹的非常詳細,零基礎也能參考此文章,感興趣的小伙伴們可以參考一下。

創新互聯公司是專業的邛崍網站建設公司,邛崍接單;提供網站設計、成都網站制作,網頁設計,網站設計,建網站,PHP網站建設等專業做網站服務;采用PHP框架,可快速的進行邛崍網站開發網頁制作和功能擴展;專業做搜索引擎喜愛的網站,專業的做網站團隊,希望更多企業前來合作!

消耗內存最嚴重的對象創建過程,必須對其進行約束,作為創建型模式的單例模式(Singleton),始終保持應用程序中某一個實例有且僅有一個,可以很顯著的提升程序性能。

 單線程下的Singleton的穩定性是極好的,可分為兩大類:

1.Eager(餓漢型): 類加載時立即創建對象。

public class EagerSingleton {
    //1. 類加載時就立即產生實例對象,通過設置靜態變量被外界獲取
    //2. 并使用private保證封裝安全性
    private static EagerSingleton eagerSingleton  = new EagerSingleton();
    
    //3. 通過構造方法的私有化,不允許外部直接創建對象,確保單例的安全性
    private EagerSingleton(){
    }
    public static EagerSingleton getEagerSingleton(){
        return eagerSingleton;
    }

2.Lazy(懶漢型):類加載時沒有立即創建對象,等到第一個用戶獲取才進行實例化。

public class LazySingleton {
    //1. 類加載時并沒有創建唯一實例
    private static LazySingleton lazySingleton;
    
    private LazySingleton() {
    }
        
    //2、提供一個獲取實例的靜態方法
    public static LazySingleton getLazySingleton() {
        if (lazySingleton == null) {
            lazySingleton = new LazySingleton();
        } 
        return lazySingleton;
    }

就性能方面而言,LazySingleton 明顯優于 EagerSingleton ,若類的加載需要耗費大量的資源(e.g. 讀取大文件信息),那么LazySingleton 的優勢顯而易見。但通過閱讀代碼,很容易發現一個致命問題。多線程間如何保持安全性?

下面將對多線程并發問題進行解析:

解決該問題的關鍵在于兩方面:1.同步;  2.性能;

如何解救呢?
作為一個java的開發者,對synchronized一定不陌生,提到多線程,大部分人想到的都是他(JDK6后,他的性能提升巨大,解決簡單并發,非常適用)。

那就讓我們用synchronized來嘗試解決吧:

//由synchronized進行同步加鎖
public synchronized static LazySingleton getLazySingleton() {
        if (lazySingleton == null) {
            lazySingleton = new LazySingleton();
        } 
        return lazySingleton;
    }

如此同步問題看似解決,但是作為一個開發者,最重要的是性能的保障,使用synchronized有利有弊,由于加鎖操作,代碼段被加上悲觀鎖,只有等一個請求完成,下個請求才能進入執行。通常加上synchronized關鍵字的代碼片會比同等量級的代碼慢上幾倍,這是我們不愿見到的。那如何避免這一問題呢?在java對synchronized的定義里有這樣的建議:越遲使用synchronized,性能越優(細化鎖)。

###### 2.因此,我們需要開始解決性能的問題了。按照synchronized優化: ######

public class DoubleCheckLockSingleton {
    //使用volatile保證每次取值不是從緩存中取,而是從真正對應的內存地址中取.(下文解釋)
    private static volatile DoubleCheckLockSingleton doubleCheckLockSingleton;
    
    private DoubleCheckLockSingleton(){
        
    }
    
    public static DoubleCheckLockSingleton getDoubleCheckLockSingleton(){
        //配置雙重檢查鎖(下文解釋)
        if(doubleCheckLockSingleton == null){
            synchronized (DoubleCheckLockSingleton.class) {
                if(doubleCheckLockSingleton == null){
                    doubleCheckLockSingleton = new DoubleCheckLockSingleton();
                }
            }
        }
        return doubleCheckLockSingleton;
    }
}

上述源碼就是經典的volatile關鍵字(JDK1.5 后重生)+雙重檢查鎖(DoubleCheck),大程度的優化了sychronized帶來的性能開銷。下面將為大家解釋volatile與DoubleCheck。

1.volatile

是在JDK1.5后才正式被實現使用的,之前的版本只是定義了該關鍵字,未有具體實現。若想理解volatile就必須對JVM自身的內存管理有些許了解:

1.1 遵循著摩爾定律,內存的讀寫速度已遠不能滿足CPU,因此現代計算機引入了在CPU上添加高速緩存的機制,由緩存預讀取內存的值,并暫存于緩存中,通過計算,再更新內存中的相應值。

**1.2** 而JVM模仿PC的這一做法,在內存中劃分了自己的**工作內存**,該部分內存作用與高速緩存一致,很顯著的提高JVM工作效率,但凡事都有利有弊,這一做法也導致工作內存與其他內存通信時容易導致傳輸上的問題。volatile的一個功能就是強制的從內存中讀取最新的值,避免緩存與內存不一致的狀況。

1.3 volatile的另一個功能也是和JVM相關,即JVM會通過自身的判斷,將源碼的執行順序重排,保證指令流水線連貫性,以達到最優的執行方案。這種做法提高了性能,但對DoubleCheck卻會產生意想外的結果,兩線程可能互相干擾。而volatile提供了happens-before guarantee(寫優先于讀),使對象不被干擾,保證安全的穩定性。

2.DoubleCheck

這是現代編程的遺留,假設進入同步塊之后,對象已被實例化,此時需再次進行判斷。

當然還有一種官方推薦的單例實現方法

由于類的構造在定義中已是原子性的,因此上述的各種問題都不會再產生,是一種很好的單例實現方式,推薦使用。

//使用內部類進行單例構造
public class NestedClassSingleton {
    private NestedClassSingleton(){
        
    }
    private static class SingletonHolder{
        private static final NestedClassSingleton nestedClassSingleton = new NestedClassSingleton();
    }
    public static NestedClassSingleton getNestedClassSingleton(){
        return SingletonHolder.nestedClassSingleton;
    }
}

看完上述內容,你們掌握實現singleton的四種方法的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創新互聯行業資訊頻道,感謝各位的閱讀!

網站名稱:實現singleton的四種方法-創新互聯
文章鏈接:http://m.newbst.com/article20/hpjco.html

成都網站建設公司_創新互聯,為您提供網站導航面包屑導航網站建設手機網站建設定制網站云服務器

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

小程序開發