單例模式
• 核心作用:
– 保證一個類只有一個實例,並且提供一個訪問該實例的全局訪問點。
• 常見應用場景:
– Windows的Task Manager(任務管理器)就是很典型的單例模式
– windows的Recycle Bin(回收站)也是典型的單例應用。在整個系統運行過程中,回收站一直維護着僅有的一個實例。
– 項目中,讀取配置文件的類,一般也只有一個對象。沒有必要每次使用配置文件數據,每次new一個對象去讀取。
– 網站的計數器,一般也是採用單例模式實現,否則難以同步。
– 應用程序的日誌應用,一般都何用單例模式實現,這一般是由於共享的日誌文件一直處於打開狀態,因爲只能有一個實例去操作 ,否則內容不好追加。
– 數據庫連接池的設計一般也是採用單例模式,因爲數據庫連接是一種數據庫資源。
– 操作系統的文件系統,也是大的單例模式實現的具體例子,一個操作系統只能有一個文件系統。
– Application 也是單例的典型應用(Servlet編程中會涉及到)
– 在Spring中,每個Bean默認就是單例的,這樣做的優點是Spring容器可以管理
– 在servlet編程中,每個Servlet也是單例
– 在spring MVC框架/struts1框架中,控制器對象也是單例
• 單例模式的優點:
– 由於單例模式只生成一個實例,減少了系統性能開銷,當一個對象的產生需要 比較多的資源時,如讀取配置、產生其他依賴對象時,則可以通過在應用啓動 時直接產生一個單例對象,然後永久駐留內存的方式來解決
– 單例模式可以在系統設置全局的訪問點,優化環共享資源訪問,例如可以設計 一個單例類,負責所有數據表的映射處理
• 常見的五種單例模式實現方式:
– 主要:
• 餓漢式(線程安全,調用效率高。 但是,不能延時加載。)
• 懶漢式(線程安全,調用效率不高。 但是,可以延時加載。)
– 其他:
• 雙重檢測鎖式(由於JVM底層內部模型原因,偶爾會出問題。不建議使用)
• 靜態內部類式(線程安全,調用效率高。 但是,可以延時加載)
• 枚舉單例(線程安全,調用效率高,不能延時加載)
具體代碼實現:
餓漢式:
package an.sz.simplefactory.singleton;
/***
* 單例模式:餓漢式
* 線程安全,效率高,不能延時加載
*/
public class SingletonHungry {
/*無論之後需不需要都已經創建好對象*/
private static SingletonHungry single = new SingletonHungry();
/*私有化構造器*/
private SingletonHungry(){}
public static SingletonHungry getInstance(){
return single;
}
}
懶漢式:
package an.sz.simplefactory.singleton;
/***
* 單例模式:餓漢式
* 線程安全,效率高,不能延時加載
*/
public class SingletonHungry {
/*無論之後需不需要都已經創建好對象*/
private static SingletonHungry single = new SingletonHungry();
/*私有化構造器*/
private SingletonHungry(){}
public static SingletonHungry getInstance(){
return single;
}
}
雙重檢測鎖式:
package an.sz.simplefactory.singleton;
/***
* 單例模式:雙重檢測鎖模式
* 提高了執行的效率,但偶爾會出現問題,不建議使用
*/
public class SingletonLock {
private static SingletonLock single;
private SingletonLock(){}
public static SingletonLock getInstatnce(){
if(single==null){
synchronized (SingletonLock.class){
single = new SingletonLock();
}
}
return single;
}
}
枚舉式:
package an.sz.simplefactory.singleton;
/***
* 單例模式:枚舉模式
* 線程安全,調用效率高,不能延時加載
*/
public enum SingletonEnum {
/*定義一個枚舉的元素,它就代表了Singleton的一個實例*/
single;
public void optertion(){
/*每個實例可以有自己的功能*/
}
}
靜態內部類式:
package an.sz.simplefactory.singleton;
/***
* 單例模式:靜態內部類式
* 線程安全,調用效率高,可以延時加載
*/
public class SingletonInnerClass {
private static class SingleInstance{
private static SingletonInnerClass single = new SingletonInnerClass();
}
private SingletonInnerClass(){}
public static SingletonInnerClass getInstance(){
return SingleInstance.single;
}
}