建立型模式--單例模式(Singleton)
阿新 • • 發佈:2019-01-05
Singleton:Ensure a class only has one instance, and provide a global point of access to it.
一個類只能有一個例項的建立模式。
一:引入
在某些情況下一個類只能有一個例項,如果多於一個例項就會導致邏輯錯誤。
- 非共享資源:如印表機,系統屬性檔案
- 其他:如資料庫主鍵生成器,只能有一個地方分配,否則會出現重複主鍵
- EagerSingleton(餓漢式單例):
* 餓漢式單例
*/
publicclass EagerSingleton {
//類載入時例項化
privatestatic
//建構函式設為私有,不能以new的方式生成新的例項
private EagerSingleton()
{
}
//提供給客戶的得到唯一例項的方法
publicstatic EagerSingleton getInstance()
{
return instance;
}
} publicclass Client {
publicstaticvoid main(String args[])
EagerSingleton s1 = EagerSingleton.getInstance();
EagerSingleton s2 = EagerSingleton.getInstance();
if( s1 == s2 )
System.out.println( "s1 == s2" );
}
}
問題:
- 類在載入時就將自己例項化,對於象資源控制器之類的類初始化可能耗費很多時間。還可能會導致出現多執行緒首次同時引用子類的機率變得比較大。
- 建構函式為私有,不能被繼承。
- LazySingleton(懶漢式單例)--延遲載入(訪問時載入)
* 懶漢式單例
*/
publicclass LazySingleton {
//類載入時為null,不例項化
privatestatic LazySingleton instance=null;
//建構函式設為私有,不能以new的方式生成新的例項
private LazySingleton()
{
}
//提供給客戶的得到唯一例項的方法
publicstatic LazySingleton getInstance()
{
//如果沒有建立例項就建立,否則就用以前建立了的那個。
if (instance==null) instance=new LazySingleton();
return instance;
}
}
- 第一次訪問時例項化,資源利用效率比餓漢式要好,但第一次訪問時反應時間不如餓漢式。
- 因為建構函式私有,也不能被繼承。
上例沒有考慮到多執行緒環境,如果第一個執行緒執行到 if(instance==null)且還沒有執行instance=new LazySingleton()時,另一個執行緒也執行到 if(instance==null)這時條件也為true,所以也會執行new LazySingleton()導致多例項。
//整個方法都加鎖,防止多執行緒環境下的問題synchronizedpublicstatic LazySingleton getInstance()
{
//如果沒有建立例項就建立,否則就用以前建立了的那個。
if (instance==null) instance=new LazySingleton();
return instance;
} /**
* 懶漢式單例,多執行緒環境
*/
publicclass LazySingleton {
// 類載入時為null,不例項化.
// volatile ensures that multiple threads handle the instance variable
// correctly
// when it is being initialized to the Singleton instance.
privatevolatilestatic LazySingleton instance =null;
// 建構函式設為私有,不能以new的方式生成新的例項
private LazySingleton() {
}
// 兩階段加鎖,防止多執行緒環境下的問題,效率比整個方法加鎖高。
publicstatic LazySingleton getInstance() {
// 如果沒有建立例項就建立,否則就用以前建立了的那個。
if (instance ==null) {
synchronized (LazySingleton.class) {
if (instance ==null) {
instance =new LazySingleton();
}
}
}
return instance;
}
}
二:結構
三:實際應用
- java.lang.Runtime
privatestatic Runtime currentRuntime =new Runtime();
/**
* Returns the runtime object associated with the current Java application.
* Most of the methods of class <code>Runtime</code> are instance
* methods and must be invoked with respect to the current runtime object.
*
* @return the <code>Runtime</code> object associated with the current
* Java application.
*/
publicstatic Runtime getRuntime() {
return currentRuntime;
}
/** Don't let anyone else instantiate this class */
private Runtime() {}
}
四:適用情形
Use the Singleton pattern when
there must be exactly one instance of a class, and it must be accessible to clients from a well-known access point. when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying參考文獻:
1:閻巨集,《Java與模式》,電子工業出版社
2:Eric Freeman & Elisabeth Freeman,《Head First Design Pattern》,O'REILLY