java單例模式(Singleton)以及實現 java單例模式(Singleton)以及實現 java單例模式(Singleton)以及實現 一. 什麼是單例模式 因程式需要,有時我們只需要某個類同時保留一個對象,不希望有更多對象,此時,我們則應考慮單例模式的設計。 二. 單例模式的特點 1. 單 ...
java單例模式(Singleton)以及實現
一. 什麼是單例模式
因程式需要,有時我們只需要某個類同時保留一個對象,不希望有更多對象,此時,我們則應考慮單例模式的設計。
二. 單例模式的特點
1. 單例模式只能有一個實例。
2. 單例類必須創建自己的唯一實例。
3. 單例類必須向其他對象提供這一實例。
三. 單例模式與靜態類區別
在知道了什麼是單例模式後,我想你一定會想到靜態類,“既然只使用一個對象,為何不幹脆使用靜態類?”,這裡我會將單例模式和靜態類進行一個比較。
1. 單例可以繼承和被繼承,方法可以被override,而靜態方法不可以。
2. 靜態方法中產生的對象會在執行後被釋放,進而被GC清理,不會一直存在於記憶體中。
3. 靜態類會在第一次運行時初始化,單例模式可以有其他的選擇,即可以延遲載入。
4. 基於2, 3條,由於單例對象往往存在於DAO層(例如sessionFactory),如果反覆的初始化和釋放,則會占用很多資源,而使用單例模式將其常駐於記憶體可以更加節約資源。
5. 靜態方法有更高的訪問效率。
6. 單例模式很容易被測試。
四.幾個關於靜態類的誤解:
誤解一:靜態方法常駐記憶體而實例方法不是。
實際上,特殊編寫的實例方法可以常駐記憶體,而靜態方法需要不斷初始化和釋放。
誤解二:靜態方法在堆(heap)上,實例方法在棧(stack)上。
實際上,都是載入到特殊的不可寫的代碼記憶體區域中。
五.靜態類和單例模式情景的選擇:
情景一:不需要維持任何狀態,僅僅用於全局訪問,此時更適合使用靜態類。
情景二:需要維持一些特定的狀態,此時更適合使用單例模式。
六.本人特意寫了一個單例的詳細代碼獻上 (主要是單例懶漢式,餓漢式詳解)
創建一個學生Student對象,寫成兩個類,餓漢式為Student_1,懶漢式為Student_2
1 public class Student_1 { 2 //餓漢式 3 private static Student_1 student = new Student_1(); 4 public static Student_1 newInstance() { 5 return student; 6 } 7 8 public Student_1() { 9 System.out.println("餓漢式創建對象"); 10 } 11 } 12 13 14 class Student_2 { 15 //懶漢式 16 private static Student_2 student2; 17 18 static Student_2 newInstance2() { 19 //提高效率,如果第一次創建對象成功,後面就不用進入同步當中,直接返回對象即可 20 if (student2 == null) { 21 synchronized (Student_1.class) { 22 //如果是第一次調用方法,進入if,創建對象 23 if (student2 == null) { 24 student2 = new Student_2(); 25 } 26 } 27 } 28 return student2; 29 } 30 31 public Student_2() { 32 System.out.println("懶漢式雙重檢驗創建對象"); 33 } 34 35 }
1 public class Danli_1 { 2 /* 3 * 單例:一個類只允許被創建1次對象 4 * 餓漢式 HungrySingLeton 5 * 懶漢式 LazySingLeton 6 */ 7 8 public static void main(String[] args) { 9 /* 10 * 單例:一個類只允許被創建1次對象 11 * 餓漢式 HungrySingLeton 12 * 1:構造器私有化 13 * 2:初始化一個私有靜態的對象 14 * 3:提供一個公開的靜態的獲取對象的方法 15 * 註意 16 * 1:對象產生的時間:類載入的時候就被創建了 17 * 優點:代碼簡單,安全性較高 18 * 缺點:創建對象時機過早,有可能會浪費記憶體空間 19 * 懶漢式 LazySingLeton 20 */ 21 22 Student_1 s =Student_1.newInstance(); 23 /* 24 * 單例:懶漢式:什麼時候用什麼時候創建對象 25 * 1:構造器私有化 26 * 2:聲明一個私有的靜態的對象變數 27 * 3:提供一個公開的靜態獲取對象的方法 28 * 29 * 註意:創建時間恰當 30 * 註意:多線程的情況下,容易出現多個對象 31 * 使用雙重校驗法 32 */ 33 Student_2 s2 =Student_2.newInstance2(); 34 35 } 36 }
Java的異常機制:鏈接:https://pan.baidu.com/s/1mFhLXCwM071JPNPVKZIoRA 提取碼:eiok