擁有獨立且惟一的對象
此次講述的是單件模式,就是整個內容裏只有一個實例化「惟一」對象。這麼說可能有點拗口,這麼說吧,比方說,線程池,緩存,註冊表,日誌文件,甚至作JDBC中鏈接,關閉,增刪改查數據庫的Connection類(我的命名也許並不同)、工具類等等。這些東西每每是要實例一次,就能在整個項目中使用了。java
單件模式並不難理解定義以下
單件模式:確保一個類中只有一個實例,並提供一個全局訪問點。
是的就這麼一句話的定義。通常單件模式分爲「懶漢式」和「餓漢式」作法數據庫
直接上代碼。編程
「懶漢式」作法設計模式
package singleton01; public class Singleton01 { // 利用一個靜態變量記錄本類當中惟一的實例(mySingleton01) private static Singleton01 mySingleton01 = null; public Singleton01() { } // synchronized關鍵字:線程同步鎖,在多線程中去互斥地訪問臨界資源 // 迫使每一個線程在進入方法以前,要先等別的線程執行完離開方法後才能執行,達到多個線程排隊,不會形成有多個線程同時進入這個方法 // 便是同步。但同步會使程序效率下降 public static synchronized Singleton01 getInstance() { if (mySingleton01 == null) { mySingleton01 = new Singleton01(); System.out.println("Singleton01被實例化了"); } System.out.println("返回Singleton01實例"); return mySingleton01; } /** * 上面方法就是常說了「懶漢式」作法,大致意思就是當誰須要類方法時採起實例化 */ }
package singleton01; public class TestMain { public static void main(String[] args) { // 打印出前兩行結果 Singleton01 singleton01 = Singleton01.getInstance(); // 此時咱們看到第二次調用類方法時候,沒有去實例對象 // 這裏涉及併發方面問題,暫時沒學習併發,具體怎麼個原理我也不知道... Singleton01 singleton02 = Singleton01.getInstance(); } }
效果圖1
緩存
效果圖2
多線程
以前的作法中咱們用到了synchronized,就是爲了防止線程啓動的隨機性找出變量混亂,我這個小例子可能看不出來什麼。但實際上同步線程(synchronized)會使得程序效率大幅下降。利用雙重檢查加鎖能夠有效解決此問題,併發
使用雙重檢查加鎖工具
package singleton01; public class singleton02 { // 利用雙重檢查加鎖,先檢查實例是否已經建立,若是沒建立,就進行同步。 // volatile:instance變量被初始化singleton02實例時,多個線程會正確處理instance變量 // 線程是具備隨機性的,與程序執行順序無關。 private volatile static singleton02 instance=null; public singleton02() { } public static singleton02 getInstance() { if (instance == null) { // 檢查實例,不存在的話進入同步區域,只有第一次才執行這裏 synchronized (singleton02.class) { System.out.println("進入同步區域"); if (instance == null) { System.out.println("instance被實例化了"); instance = new singleton02(); } } } System.out.println("返回instance實例"); return instance; } }
package singleton01; public class TestMain02 { public static void main(String[] args) { //第一次進入方法會進入同步區實例化 singleton02 singleton02 = null; singleton02 = singleton02.getInstance(); //當第二次進入時,已有實例,不會同步了,直接返回實例. singleton02 singleton03 = null; singleton03 = singleton02.getInstance(); } }
效果圖
學習
"餓漢式"作法spa
package singleton02; public class Singleton { /** * 「餓漢式」:加載這個類時馬上建立本類中惟一的單件實例, */ private static Singleton uniqueInstance = new Singleton(); private Singleton() { } public static Singleton getInstance() { System.out.println("返回實例實例"); return uniqueInstance; } }
package singleton02; public class TestMain { public static void main(String[] args) { //直接返回實例 Singleton singleton = Singleton.getInstance(); } }
效果圖
注:雙重檢查加鎖不適用與1.4以前的java版本。
要點:
一、單件模式確保程序中一個類最多隻有一個實例。
二、單件模式提供這個實例的全局訪問點。
三、實現單件模式,須要私有構造器,一個靜態方法,一個靜態變量。
四、設計到多線程問題,同步會下降程序效率。
感謝你看到這裏,至此單件模式內容結束,本人文筆隨便,如有不足或錯誤之處望給予指點,90度彎腰~~~很快我會發佈下一個設計模式內容,生命不息,編程不止!
參考書籍:《Head First 設計模式》