1. 程式人生 > >單例模式中的Double check lock

單例模式中的Double check lock

Double check lock

package test;
public class Singleton {
    public static Singleton singleton;
    private Singleton(){
    }
    public static Singleton getInstance(){
        if(singleton==null){
            synchronized(Singleton.class){
                if(singleton==null){
                    singleton=new
Singleton(); return singleton; } } } return singleton; } }

第8行中第一個check是為了檢查當前是否已經生成singleton,如果有了,就不進行同步,直接獲取singleton,節省資源。
如果檢查到沒有生成singleton,那麼當前執行緒鎖定Singleton類,生成一個新的Singleton例項。
第二個check是考慮到這樣一種情況。
執行緒A在第8行中檢測到singleton為空到第11行完成Singleton生成之間,執行緒B也檢測到singleton也沒空,也準備進入鎖定Singleton類。
執行緒A完成Singleton類生成並釋放同步塊。執行緒B進入同步,執行第10行的檢測,如果singleton已經生成了,就不執行生成。

為了防止執行緒B儲存一份singleton值的複製,可以定義singleton為volatile,這樣,在每次檢查singleton時,都需要重新讀取singleton的值,每次賦值完後,都要重新寫入。

至於執行緒安全的單例模式,可以不用這種方法,直接使用列舉類。
所有的列舉項都是static final形式,也就是說,它們在使用前只能被構造一次,而且是唯一的一次。
列舉項INSTANCE的構造過程都是執行緒安全的,省去了諸如volatile,synchronized這些需要考慮的東西。

package test;
/*
 * 採用列舉類的全域性計數器
 * 注意INSTANCE的構造是執行緒安全,而且唯一的。但是其中的方法的使用卻不是執行緒安全的。
 */
import java.util.UUID; public class SingletonUsingEnum { enum Singleton{ INSTANCE; //例項的唯一標識 private String Id=UUID.randomUUID().toString(); private int counter; public String getId(){ return this.Id; } public void increment(){ counter++; } public int getValue(){ return counter; } } }

相關推薦

模式Double check lock

Double check lock package test; public class Singleton { public static Singleton singleton; private Singleton(){ }

Java 模式使用雙重檢查(Double-Check

在 Effecitve Java 一書的第 48 條中提到了雙重檢查模式,並指出這種模式在 Java 中通常並不適用。該模式的結構如下所示: public Resource getResource() {     if (resource == null)

你所不知道的模式和多線程並發在模式的影響

影響 編程問題 rop key 是我 提升 註意 特性 是不是 單例對象(Singleton)是一種常用的設計模式。在Java應用中,單例對象能保證在一個JVM中,該對象只有一個實例存在。這樣的模式有幾個好處: 1、某些類創建比較頻繁,對於一些大型的對象,這是一筆很大的系

Java基礎 Runtime 用了模式的餓漢式

face ring lang run ice ffi new es2017 obj 禮悟: 好好學習多思考,尊師重道存感恩。葉見尋根三返一,活水清源藏於零。 虛懷若谷良心主,皓月當空自在王。願給最苦行無悔,誠勸且行且珍惜。

模式為什麽用枚舉更好

cells 變量 講解 pad table resolv 單例模式 關鍵字 comm 枚舉單例(Enum Singleton)是實現單例模式的一種新方式,盡管單例模式在java中已經存在很長時間了,但是枚舉單例相對來說是一種比較新的概念,枚舉這個特性是在Java5才出現的,

模式的餓漢式和懶漢式

img image bubuko 圖片 bsp 懶漢 餓漢式 單例模式 http 餓漢式單例: 懶漢式單例 單例模式中的餓漢式單例和懶漢式單例

模式的雙重檢查加鎖

本文是在學習單例模式時遇到的問題 在多執行緒中,如何防止單例模式被多次例項,當然是要加鎖啦。但是加了鎖就意味著執行緒雖然安全,但效率肯定會變低,這是,就出現了雙重檢查加鎖。但看到這段程式碼,我又有疑問了? public class Singleton { private vo

spring模式,執行緒安全問題

@RequestMapping(value = "getPsdbData", method = RequestMethod.POST) public Map<String, Object> getPsdbData(String key,HttpServletRequest reques

模式成員變數為什麼一定要是私有的private

package danLi; public class AA { public static AA aa = new AA(); private AA() {} } //------------------------------------------ package

模式懶漢模式與餓漢模式

/** * @author 萬星明 * @version 建立時間:2018年10月26日 下午4:32:10 * 請編寫一個單例模式,類名自己定義(不允許出現無意義命名)。 * 分別用懶

模式靜態類成員變數初始化問題

    最近做一個專案,C++語言,使用到了單例模式做設計。在具體編寫程式碼時,使用了靜態成員變數和靜態函式。程式碼如下: class Camera { private: //(省略若干程式碼) static Camera* pCamera ; //(省略若干

模式可能存在的一些問題(執行緒安全問題)

單例的設計模式中,一些程式碼的寫法會存線上程安全的問題,舉例如下:(1)單例模式的懶漢式[執行緒不安全,不可用] public class Singleton { private static Singleton instance=nu

全域性變數誤用導致模式的多次銷燬例項產生coredump

最近遇到一個問題,產生了coredump, 用gdb看也沒看出真正原因,合作方同事提醒才看出來。 模擬了一下出錯場景,程式碼如下:   class Person{ private: int *m_data; static Person *

C++ 模式懶漢式與餓漢式

應該都知道一個單例模式怎樣去實現: 1、建構函式宣告為private或protect防止被外部函式例項化。 2、提供一個全域性的靜態方法(全域性訪問點)。 3、內部儲存一個private static的類指標儲存唯一的例項,例項的動作由一個public的類方法代勞,該方法也

模式,餓漢式和懶漢式有什麼區別?各適合用在哪裡?為什麼說推薦用餓漢模式

 餓漢式:        public class Singleton{            private static Singleton singleton = new Singleton ();            private Singleton (){}            public

模式,惡漢式和懶漢式有哪些區別。各使用在哪裡?為什麼說推薦使用惡漢式

餓漢式:        public class Singleton{            private static Singleton singleton = new Singleton ();            private Singleton (){}  

模式的懶漢模式和惡漢模式的區別

單例模式在我們開發中經常會用到的,不知道你所喜歡用餓漢模式還是喜歡懶漢模式呢?為什麼會出現有兩種方式來實現單例模式? 我看這其中必蹊蹺,你怎麼看? 大家都知道的是:懶漢模式會通過 判 null,然後 new 出一個例項,也就是懶漢模式會延遲加載出例項物件。還

Java模式的飽漢式和飢漢式

Java中單例模式是筆試的常見題目,包括飽漢式和飢漢式,具體程式碼實現如下:飽漢式:public class SingleTon { private SingleTon(){} priv

多執行緒學習筆記(三)之模式的執行緒問題

在某些情況下,每個類只需要一個例項,單例模式就是保證在整個應用程式的生命週期中,任何一個時刻,單例類的例項都只存在一個(當然也可以不存在),核心點: 將採用單例模式的類的構造方法私有化(private修飾) 在其內部產生該類的例項化物件,並將其封裝成priv

java模式雙重檢查鎖定的volatile的作用解析

volatile對singleton的建立過程的重要性:禁止指令重排序(有序性)例項化一個物件其實可以分為三個步驟:  (1)分配記憶體空間。  (2)初始化物件。  (3)將記憶體空間的地址賦值給對應的引用。但是由於作業系統可以對指令進行重排序,所以上面的過程也可能會變成如下過程:  (1)分配記憶體空間。