單例模式的含義java
單例模式的意思就是隻有一個實例。單例模式確保某一個類只有一個實例,並且自行實例化並向整個系統提供這個實例。安全
通常只有一個私有的構造方法,它能夠經過調用公共的靜態方法來得到這個實例。多線程
單例模式的好處併發
主要做用是保證在Java應用程序中,一個類Class只有一個實例存在。性能
使用Singleton的好處還在於能夠節省內存,由於它限制了實例的個數,有利於Java垃圾回收this
單例模式特色spa
一、單例類只能有一個實例。線程
二、單例類必須本身建立本身的惟一實例。code
三、單例類必須給全部其餘對象提供這一實例。對象
單例模式的選型:
在實現層面上,目前的幾種主要的單例模式每每有如下幾項性能指標做爲選型參考:
-- 是否實現延遲加載
-- 是否線程安全
-- 併發訪問性能
-- 是否能夠防止反射與反序列化穿透
一個線程訪問一個對象中的synchronized(this)同步代碼塊時,其餘試圖訪問該對象的線程將被阻塞。
1.懶漢式單例
在類加載的時候不建立單例實例。只有在第一次請求實例的時候的時候建立,而且只在第一次建立後,之後再也不建立該類的實例。
懶漢式若是在建立實例對象時不加上synchronized則會致使對對象的訪問不是線程安全的
//單例模式-懶漢式單例 public class LazySingleton { //私有靜態對象,加載時候不作初始化 private static LazySingleton m_intance=null; // 私有構造方法,避免外部建立實例 private LazySingleton(){} /** * 靜態工廠方法,返回此類的惟一實例. * 當發現實例沒有初始化的時候,才初始化. */ synchronized public static LazySingleton getInstance(){ if(m_intance==null){ m_intance=new LazySingleton(); } return m_intance; } }
2. 餓漢式單例
在類加載的時候就建立實例,,在類建立的同時就已經建立好一個靜態的對象供系統使用
/* * 單例模式-餓漢式單例 */ public class EagerSingleton { /* * 私有的(private)惟一(static final)實例成員,在類加載的時候就建立好了單例對象 */ private static final EagerSingleton m_instance = new EagerSingleton(); /** * 私有構造方法,避免外部建立實例 */ private EagerSingleton() { } /** * 靜態工廠方法,返回此類的惟一實例. * @return EagerSingleton */ public static EagerSingleton getInstance() { return m_instance; } }
3. 登記式單例
這個單例實際上維護的是一組單例類的實例,將這些實例存放在一個HashTable(登記薄)中,對於已經登記過的實例,則從工廠直接返回,對於沒有登記的,則先登記,然後返回。
//用來存儲單例(StringManager)的變量的hash類 private static HashTable managers = new HashTable(); //下面用關鍵字synchronized避免多線程時出錯。 public synchronized static StringManager getManager(String packageName){ StringManager mgr = (StringManager)managers.get(packageName); if(mgr == null){ mgr = new StringManager(packageName); managers.put(packageName,mgr); } return mgr; }
4.雙重鎖定單例(改進懶漢式)
考慮這樣一種狀況,就是有兩個線程同時到達,即同時調用 getInstance() 方法。兩個線程都會建立一個實例,這就違背了單例模式的初衷。所以加雙重鎖定
public class Singleton { private static volatile Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
啊
啊啊