單例模式的含義
單例模式的意思就是只有一個實例。單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。
一般只有一個私有的構造方法,它可以通過調用公共的靜態方法來獲得這個實例。
單例模式的好處
主要作用是保證在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;
}
}
啊
啊啊
