原理或定義
一個類能返回對象一個引用(永遠是同一個)和一個獲得該實例的方法(必須是靜態方法,通常使用getInstance這個名 稱);當我們調用這個方法時,如果類持有的引用不爲空就返回這個引用,如果類保持的引用爲空就創建該類的實例並將實例的引用賦予該類保持的引用;同時我們 還將該類的構造函數定義爲私有方法,這樣其他處的代碼就無法通過調用該類的構造函數來實例化該類的對象,只有通過該類提供的靜態方法來得到該類的唯一實例。
結構
a.私有構造方法
b.私有靜態引用指向自己實例
c.以自己實例爲返回值的公有靜態方法
類圖
分類
1.餓漢式(常用):單例實例在類裝載時就構建,急切初始化。(預先加載法)
2.懶漢式:單例實例在第一次被使用時構建,延遲初始化。
3.懶漢式-線程安全(效率不高):對比普通懶漢式加上同步關鍵字。
4.雙重檢測(資源利用率高):對比普通懶漢式是在第一次判斷裡面加一個同步塊,並且在同步塊裏再加一次判斷。
5.靜態內部類(資源利用率高):不執行getInstance()不被實例,可以執行該類其他靜態方法
代碼
1.餓漢式(常用):
public class Singleton {
private static Singleton uniqeInstance=new Singleton();
private Singleton(){
};
public static Singleton getInstance()
{
return uniqeInstance;
}
}
2.懶漢式:
public class Singleton {
private static Singleton uniqeInstance=null;
private Singleton(){
};
public static Singleton getInstance()
{
if(uniqeInstance==null)
{
uniqeInstance=new Singleton();
}
return uniqeInstance;
}
}
3.懶漢式-線程安全(效率不高):
public class Singleton {
private static Singleton uniqeInstance=null;
private Singleton(){
};
public static synchronized Singleton getInstance()
{
if(uniqeInstance==null)
{
uniqeInstance=new Singleton();
}
return uniqeInstance;
}
}
4.雙重檢測(資源利用率高):
public class Singleton {
private static Singleton uniqeInstance=null;
private Singleton(){
};
public static Singleton getInstance()
{
if(uniqeInstance==null)
{
synchronized(this){
if(uniqeInstance==null)
{
uniqeInstance=new Singleton();
}
}
}
return uniqeInstance;
}
}
5.靜態內部類(資源利用率高):
public class Singleton{
private Singleton(){}
public static Singleton getInstance(){ return Holder.SINGLETON;}
private static class Holder{//內部類
private static final Singleton SINGLETON= new Singleton();
}
}
使用場景
1.資源共享的情況下,避免由於資源操作時導致的性能或損耗等。如日誌文件,應用配置。
2.控制資源的情況下,方便資源之間的互相通信。如線程池等。
優缺點
主要優點有:
1.在單例模式中,活動的單例只有一個實例,對單例類的所有實例化得到的都是相同的一個實例。這樣就防止其它對象對自己的實例化,確保所有的對象都訪問一個實例。
2.單例模式具有一定的伸縮性,類自己來控制實例化進程,類就在改變實例化進程上有相應的伸縮性。
3.提供了對唯一實例的受控訪問。
4.由於在系統內存中只存在一個對象,因此可以 節約系統資源,當 需要頻繁創建和銷燬的對象時單例模式無疑可以提高系統的性能。
5.允許可變數目的實例。
6.避免對共享資源的多重佔用。
缺點主要有:
1.不適用於變化的對象,如果同一類型的對象總是要在不同的用例場景發生變化,單例就會引起數據的錯誤,不能保存彼此的狀態。
2.由於單利模式中沒有抽象層,因此單例類的擴展有很大的困難。
3.單例類的職責過重,在一定程度上違背了“單一職責原則”。
4.濫用單例將帶來一些負面問題,如爲了節省資源將數據庫連接池對象設計爲的單例類,可能會導致共享連接池對象的程序過多而出現連接池溢出;如果實例化的對象長時間不被利用,系統會認爲是垃圾而被回收,這將導致對象狀態的丟失。
什麼是Java中的內存泄露
內存泄漏就是存在一些被分配的對象,這些對象有下面兩個特點,首先,這些對象是可達的,即在有向圖中,存在通路可以與其相連;其次,這些對象是無用的,即程序以後不會再使用這些對象。如果對象滿足這兩個條件,這些對象就可以判定爲Java中的內存泄漏。