·核心作用: -保證一個類只有一個實例,並且提供一個訪問該實例的全局訪問點。 ·常見應用場景: -Windows的Task Manager(任務管理器)就是很典型的單例模式 -Windows的Recycle Bin(回收站)也是很典型的單例應用。在整個系統運行過程中,回收站一直維護著僅有的一個實例 ...
·核心作用:
-保證一個類只有一個實例,並且提供一個訪問該實例的全局訪問點。
·常見應用場景:
-Windows的Task Manager(任務管理器)就是很典型的單例模式
-Windows的Recycle Bin(回收站)也是很典型的單例應用。在整個系統運行過程中,回收站一直維護著僅有的一個實例
-項目中,讀取配置文件的類,一般也只有一個對象。沒有必要每次使用配置文件數據,每次new一個對象去讀取
-網站的計數器,一般也是採用單例模式實現,否則難以同步
-應用程式的日誌應用,一般都採用單例模式實現,這一般是由於共用日誌文件一直處於打開狀態,因為只能一個實例去操作,否則內容不好追加
-資料庫連接池的設計一般也是採用單例模式,因為資料庫連接是一種資料庫資源
-操作系統的文件系統,也是大的單例模式實現的具體例子,一個操作系統只能有一個文件系統
-Application也是單例的典型應用(Servlet編程中會涉及到)
-在servlet編程中,每個servlet也是單例
-在Spring中,每個Bean預設就是單例,這樣做的優點是Spring容器可以管理
-在SpringMVC框架中,控制對象(Controller)也是單例
·單例模式的優點:
-由於單例模式只生成一個實例,減少了系統性能的開銷,當一個對象的產生需要比較多的資源時,如讀取配置、產生其他依賴對象時,則可以通過在應用啟動時直接產生一 個單例對象,然後永久駐留在記憶體中的方式來解決
-單例模式可以在系統設置全局的訪問點,優化環共用資源訪問,例如可以設計一個單例類,負責所有數據表的映射處理
·常見的五種單例模式實現方式:
-主要:
餓漢式(線程安全,調用效率高。但是,不能延時載入)
懶漢式(線程安全,調用效率不高。但是,可以延時載入)
-其他:
雙重檢測鎖式(由於JVM底層內部模型原因,偶爾會出問題,不建議使用)
靜態內部類式(線程安全,調用效率高。可以延時載入)
枚舉單例(線程安全,調用效率高,不能延時載入)
/** * 餓漢式單例模式實現 * 問題:如果只是載入本類,而不是要調用getInstance(),甚至永遠沒有調用,則會造成資源的浪費 * @author XuZeSen * */ public class SingletonDemo1 { //類初始化時,立即載入這個對象(沒有延時載入的優勢),靜態變數載入是天然的線程安全 private static SingletonDemo1 instance = new SingletonDemo1(); //構造器私有化 private SingletonDemo1() { } //定義一個全局的訪問點,訪問這個單例對象,方法沒有同步,調用效率高 public static SingletonDemo1 getInstance(){ return instance; } }
/** * 懶漢式單例模式實現 * 問題:資源利用率高了,但是,每次調用getInstance()方法都要同步,併發效率較低 * @author XuZeSen * */ public class SingletonDemo2 { //類初始化時,沒有立即載入這個對象(延時載入,真正用到的時候再創建) private static SingletonDemo2 instance; //構造器私有化 private SingletonDemo2() { } //方法同步,調用效率低 public static synchronized SingletonDemo2 getInstance(){ if(null == instance){ instance = new SingletonDemo2(); } return instance; } }
/** * 雙重檢測鎖實現 * 這個模式下將內容同步到if內部,提高了執行的效率,不必每次獲取對象時都進行同步 * 只有第一次同步創建了 * @author Sen * */ public class SingletonDemo3 { private static SingletonDemo3 instance = null; private SingletonDemo3() { } public static SingletonDemo3 getInstance(){ if(null == instance){ SingletonDemo3 temp; synchronized (SingletonDemo3.class) { temp = instance; if(null == temp){ synchronized (SingletonDemo3.class) { temp = new SingletonDemo3(); } } instance = temp; } } return instance; } }
/** * 靜態內部類單例模式實現 * 外部類沒有static屬性,則不會像餓漢式那樣立即載入對象 * 兼備了併發高效調用和延時載入的優勢 * @author XuZeSen * */ public class SingletonDemo4 { //構造器私有化 private SingletonDemo4() { } //instance是static final類型,保證了記憶體中只有一個這樣的實例存在,而且只能被賦值一次,從而保證了線程安全性 private static class SingletonClassInatance{ private static final SingletonDemo4 instance = new SingletonDemo4(); } //只有真正調用getInstance(),才會載入靜態內部類。載入類時是線程安全的。 public static SingletonDemo4 getInstance(){ return SingletonClassInatance.instance; } }
/** * 枚舉式單例模式實現(沒有延時載入) * @author XuZeSen * */ public enum SingletonDemo5 { //這個枚舉元素,本身就是單例對象 INSTANCE; //添加自己需要的操作! public void singletonOperation(){ } }