singleton模式四種執行緒安全的實現
1.描述:
Singleton(單例)是設計模式的一種,為了保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。
2.主要特點:
1)單例類確保自己只有一個例項(建構函式私有:不被外部例項化,也不被繼承)。
2)單例類必須自己建立自己的例項。
3)單例類必須為其他物件提供唯一的例項。
3.單例模式的應用:
資源管理器,回收站,印表機資源,執行緒池,快取,配置資訊類,管理類,控制類,門面類,代理類通常被設計為單例類
如果程式有多個類載入器又同時使用單例模式就有可能多個單例並存就要找相應解決方法了
4.實現方法:
如果應用程式總是建立並使用單例例項或在建立和執行時開銷不大。
1).Eager initialization 餓漢式單例類(依賴jvm在載入類時建立唯一單例例項)
public class EagerSingleton { // jvm保證在任何執行緒訪問uniqueInstance靜態變數之前一定先建立了此例項 private static EagerSingleton uniqueInstance = new EagerSingleton(); // 私有的預設構造子,保證外界無法直接例項化 private EagerSingleton() { } // 提供全域性訪問點獲取唯一的例項 public static EagerSingleton getInstance() { return uniqueInstance; } }
如果開銷比較大,希望用到時才建立就要考慮延遲例項化,或者Singleton的初始化需要某些外部資源(比如網路或儲存裝置),就要用後面的方法了.
2)Lazy initialization 懶漢式單例類
public class LazySingleton { private static LazySingleton uniqueInstance; private LazySingleton() { } public static synchronized LazySingleton getInstance() { if (uniqueInstance == null) uniqueInstance = new LazySingleton(); return uniqueInstance; } }
同步一個方法可能造成程式執行效率下降100倍,完全沒有必要每次呼叫getInstance都加鎖,事實上我們只想保證一次初始化成功,其餘的快速返回而已,如果在getInstance頻繁使用的地方就要考慮重新優化了.
3)”雙檢鎖”(Double-Checked Lock)儘量將”加鎖”推遲,只在需要時”加鎖”(僅適用於java 5.0 以上版本,volatile保證原子操作)
happens-before:”什麼什麼一定在什麼什麼之前執行”,也就是保證順序性.
現在的CPU有亂序執行的能力(也就是指令會亂序或並行執行,可以不按我們寫程式碼的順序執行記憶體的存取過程),並且多個CPU之間的快取也不保證實時同步,只有上面的happens-before所規定的情況下才保證順序性.
JVM能夠根據CPU的特性(CPU的多級快取系統、多核處理器等)適當的重新排序機器指令,使機器指令更符合CPU的執行特點,最大限度的發揮機器的效能.
如果沒有volatile修飾符則可能出現一個執行緒t1的B操作和另一執行緒t2的C操作之間對instance的讀寫沒有happens-before,可能會造成的現象是t1的B操作還沒有完全構造成功,但t2的C已經看到instance為非空,這樣t2就直接返回了未完全構造的instance的引用,t2想對instance進行操作就會出問題.
volatile 的功能:
1. 避免編譯器將變數快取在暫存器裡
2. 避免編譯器調整程式碼執行的順序
優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。
public class DoubleCheckedLockingSingleton { // java中使用雙重檢查鎖定機制,由於Java編譯器和JIT的優化的原因系統無法保證我們期望的執行次序。 // 在java5.0修改了記憶體模型,使用volatile宣告的變數可以強制遮蔽編譯器和JIT的優化工作 private volatile static DoubleCheckedLockingSingleton uniqueInstance; private DoubleCheckedLockingSingleton() { } public static DoubleCheckedLockingSingleton getInstance() { if (uniqueInstance == null) { synchronized (DoubleCheckedLockingSingleton.class) { if (uniqueInstance == null) { uniqueInstance = new DoubleCheckedLockingSingleton(); } } } return uniqueInstance; } }
4)Lazy initialization holder class 滿足所有 Double-Checked Locking 滿足的條件,並且沒有顯示的同步操作
public class LazyInitHolderSingleton { private LazyInitHolderSingleton() { } private static class SingletonHolder { private static final LazyInitHolderSingleton INSTANCE = new LazyInitHolderSingleton(); } public static LazyInitHolderSingleton getInstance() { return SingletonHolder.INSTANCE; } }
相關文章
- 單例模式——執行緒安全的兩種實現單例模式執行緒
- 【設計模式】實現執行緒安全單例模式的五種方式設計模式執行緒單例
- EventBus四種執行緒交付模式執行緒模式
- Map實現執行緒安全的3種方式執行緒
- 執行緒安全使用 HashMap 的四種技巧執行緒HashMap
- Java中實現執行緒安全HashSet的幾種方法 | baeldungJava執行緒
- 執行緒建立的四種方式執行緒
- Java 多執行緒基礎(四)執行緒安全Java執行緒
- 多執行緒的三種實現方式及靜態代理模式執行緒模式
- Concurrency(四:執行緒安全)執行緒
- singleton模式的實現方法有很多種麼?模式
- 執行緒安全的單例模式執行緒單例模式
- iOS多執行緒安全-13種執行緒鎖?iOS執行緒
- 執行緒池以及四種常見執行緒池執行緒
- JDK提供的四種執行緒池JDK執行緒
- 常見的四種執行緒池執行緒
- java 四種執行緒池的使用Java執行緒
- Java四種執行緒池的使用Java執行緒
- 兩種Delphi實現Singleton模式方法 (轉)模式
- 各種執行緒池實現,pool執行緒
- 5招教你實現多執行緒場景下的執行緒安全!執行緒
- iOS多執行緒全套:執行緒生命週期,多執行緒的四種解決方案,執行緒安全問題,GCD的使用,NSOperation的使用iOS執行緒GC
- Python單例模式(Singleton)的N種實現Python單例模式
- java各種集合的執行緒安全Java執行緒
- 靜態內部類實現的單例模式是執行緒安全的單例模式執行緒
- Java實現多執行緒的三種方式Java執行緒
- ios中的執行緒安全單例實現iOS執行緒單例
- java自帶的四種執行緒池Java執行緒
- Java 四種執行緒池的用法分析Java執行緒
- Java建立多執行緒的四種方式Java執行緒
- C++ 執行緒同步的四種方式C++執行緒
- Qt 中用Q_GLOBAL_STATIC來實現執行緒安全的單例模式QT執行緒單例模式
- Java多執行緒【三種實現方法】Java執行緒
- Python實現執行緒安全佇列Python執行緒佇列
- Android執行緒篇(一)實現執行緒的幾種方法及區別Android執行緒
- JAVA中實現單例(Singleton)模式的八種方式Java單例模式
- Java建立多執行緒的幾種方式實現Java執行緒
- 關於多執行緒的兩種實現方式執行緒