單例模式中的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)分配記憶體空間。