單例模式的含義
單例模式的意思就是只有一個實例。單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。
一般只有一個私有的構造方法,它可以通過調用公共的靜態方法來獲得這個實例。
單例模式的好處
主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。
使用Singleton的好處還在於可以節省內存,因為它限制了實例的個數,有利於Java垃圾回收
單例模式特點
1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
單例模式的選型:
在實現層面上,目前的幾種主要的單例模式往往有以下幾項性能指標作為選型參考:
-- 是否實現延遲加載
-- 是否線程安全
-- 並發訪問性能
-- 是否可以防止反射與反序列化穿透
一個線程訪問一個對象中的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; } }
啊
啊啊