**單例模式:**無法使用new對乙個物件進行例項,只能呼叫內部的乙個方法,拿到乙個物件例項。
1、單例模式的好處:
單例模式適合於應用中頻繁建立的物件,如果是重量級的物件,更應該使用單例模式。比如配置檔案,如果不採用單例模式的話,每個配置檔案物件的內容都是一樣的,建立重複的物件就會浪費寶貴的記憶體,所以有必要使用單例模式,達到效能的提公升,減小了記憶體的開銷和gc的壓力。
2、單例模式實現的一般方式:
**2、單例模式實現的一般方式:
(1)餓漢模式(執行緒安全)
public class singleton1
private static singleton1 single = new singleton();
// 靜態工廠方法
public static singleton1 getinstance()
}
直接在執行這個類的時候進行一次載入,之後直接訪問。顯然,這種方法沒有起到懶載入的效果,考慮到前面提到的和靜態類的對比,這種方法只比靜態類多了乙個記憶體常駐而已。
static對乙個類的載入由jvm例項,保證只實現乙個類,所以,是執行緒安全的
(2)懶漢模式(有兩種,分為執行緒安全和執行緒不安全的)
懶載入:按需載入,用的時候再建立
a.執行緒不安全的
class singletondemo2
public static singletondemo2 getinstance()
return single;
}}
缺點:沒有考慮到執行緒安全,可能存在多個訪問者同時訪問,並同時構造了多個物件的問題
在第一次兩個執行緒併發的時候,會出現同時構造多個物件,執行緒不安全
b.執行緒安全的(進行全域性加鎖)
public class single3
public synchronized static single3 getinstance()
}
加鎖的三種方法總結:
加鎖加在類,鎖的是當前的類
加在普通方法,鎖的是當前這個new出來的類物件(同一時刻只能有乙個物件來訪問當前執行緒)
加在**塊,鎖的是當前**塊
缺點:用到鎖,涉及到底層作業系統的不斷互動來獲取鎖,獲取鎖首先要占有鎖,所以,效率不高
c.執行緒安全的(加了鎖,並且使用了雙重檢驗機制)加強版
class singleton4//懶漢式單例模式,要用兩次判空操作
// 私有構造
private singleton4() {}
private static singleton4 single = null;
// 雙重檢查
public static singleton4 getinstance() }}
return single;}}
通
常執行緒安全,但是,低概率的情況下也會執行緒不安全
一次只能是乙個執行緒操作,所以,進行了雙重判空,比b的全域性加鎖效率更高
保證了初始化的時候,兩個執行緒同時進來的時候,第二個不會再次建立single4
3、多執行緒實現單例模式的方式:
(1)static靜態**塊實現
class singleton5
private static singleton5 single = null;
// 靜態**塊
static
public static singleton5 getinstance()
}
在類載入過程中實現,具體在使用階段獲取
(2)使用內部靜態類(推薦使用)
class singleton6
// 靜態內部類
private static class innerobject
public static singleton6 getinstance()
}
使用內部類的好處是,靜態內部類不會在單例載入時就載入,而是在呼叫getinstance()方法時才進行載入,達到了類似懶漢模式的效果,而這種方法又是執行緒安全的。
(3)使用內部列舉類進行實現(推薦使用)
class singletonfactory 7
public singleton7 getinstance()
}public static singleton7 getinstance()
}
更簡潔,無償地提供了序列化機制,絕對防止對此例項化,即使是在面對複雜的序列化或者反射攻擊的時候。但是它仍然不是完美的——比如,在需要繼承的場景,它就不適用了
4、單例模式與靜態類的區分
「既然只使用乙個物件,為何不乾脆使用靜態類?」
(1)單例可以繼承和被繼承,方法可以被override,而靜態方法不可以。
(2)靜態方法中產生的物件會在執行後被釋放,進而被gc清理,不會一直存在於記憶體中。
(3)靜態類會在第一次執行時初始化,單例模式可以有其他的選擇,即可以延遲載入。
(4)基於2, 3條,由於單例物件往往存在於dao層(例如sessionfactory),如果反覆的初始化和釋放,則會占用很多資源,而使用單例模式將其常駐於記憶體可以更加節約資源。
(5)靜態方法有更高的訪問效率。
(6)單例模式很容易被測試。
5、幾個關於靜態類的誤解:
誤解一:靜態方法常駐記憶體而例項方法不是。
實際上,特殊編寫的例項方法可以常駐記憶體,而靜態方法需要不斷初始化和釋放。
誤解二:靜態方法在堆(heap)上,例項方法在棧(stack)上。
實際上,都是載入到特殊的不可寫的**記憶體區域中。
6、靜態類和單例模式情景的選擇:
情景一:不需要維持任何狀態,僅僅用於全域性訪問,此時更適合使用靜態類。
情景二:需要維持一些特定的狀態,此時更適合使用單例模式。
設計模式 一 單例模式
思路 1 如果其他程式能夠隨意用new建立該類物件,那麼就無法控制個數。因此,不讓其他程式用new建立該類的物件。2 既然不讓其他程式new該類物件,那麼該類在自己內部就要建立乙個物件,否則該類就永遠無法建立物件了。3 該類將建立的物件對外 整個系統 提供,讓其他程式獲取並使用。步驟 1 將該類中的...
設計模式(一) 單例模式
這種模式只涉及到乙個單一的類,該類負責建立自己的物件,並確保只建立乙個物件。單例只有乙個例項 單例類必須建立自己唯一的例項 單例類必須給其他物件提供這唯一的例項 由於當今的程式設計模型都是基於多執行緒方式,因此此處只介紹執行緒安全的幾種實現。第一次被呼叫時才建立物件,屬於懶載入 lazy init ...
設計模式(一) 單例模式
單例模式 保證執行記憶體中只有乙個實體的實現模式就是單例模式,最常見的有餓漢模式 懶漢模式兩種。餓漢模式 package com.madg.design.singleton public class hungry public hungry getinstance 懶漢模式 package com....