java-單例詳解

大暑發表於2019-01-08

一. 什麼是單例模式

  因程式需要,有時我們只需要某個類同時保留一個物件,不希望有更多物件,此時,我們則應考慮單例模式的設計。

 

二. 單例模式的特點

  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 

相關文章