單例模式幾種比較常見的寫法

2021-09-28 12:39:00 字數 1472 閱讀 3777

1.餓漢式

這個就不用說了,直接類載入的時候例項化static ,這種方法缺點很明顯,沒用到該例項就去例項化,占用記憶體空間。

2.餓漢式

2.1 雙重檢測模式

/**

* @description:

* @author: lizijian

* @date: 2019/10/11 09:22

*/public final class singleinstance

public static singleinstance getinstance()

synchronized (singleinstance.class)

return instance;}}

}

這裡有個重要的地方是必須加volatile關鍵字,要理解為什麼要加volatile,首先要理解new singleinstance()做了什麼。new乙個物件有幾個步驟。1.看class物件是否載入,如果沒有就先載入class物件,2.分配記憶體空間,初始化例項,3.呼叫建構函式,4.返回位址給引用。而cpu為了優化程式,可能會進行指令重排序,打亂這3,4這幾個步驟,導致例項記憶體還沒分配,就被使用了。

再用執行緒a和執行緒b舉例。執行緒a執行到new singleinstance(),開始初始化例項物件,由於存在指令重排序,這次new操作,先把引用賦值了,還沒有執行建構函式。這時時間片結束了,切換到執行緒b執行,執行緒b呼叫new singleinstance()方法,發現引用不等於null,就直接返回引用位址了,然後執行緒b執行了一些操作,就可能導致執行緒b使用了還沒有被初始化的變數。

加了volatile之後,就保證new不會被指令重排序。

至此,這就是乙個完整的懶漢模式—>執行緒安全的->雙重檢查加鎖單例模式。

2.2 內部類載入單例

class singleinstance

private static class lazysomethineholder

public static singleinstancegetinstance()

}

這種是我個人認為最好也是比較常用的方法,簡單,沒有執行緒安全問題。

2.3 列舉實現單例

列舉非常適合單例,因為列舉型別不允許繼承,執行緒安全且只能例項化一次。列舉類和餓漢式差不多,當它的class物件被載入就會例項化列舉型別的例項變數,可以改造為懶載入。如下

public final class singleinstance 

public static singleinstance getinstance()

private enum enumsingleinstanceholder

public singleinstance getinstance()

}}

單例模式幾種寫法

1.餓漢式 public class singleton public static singleton getinstance 2.懶漢式 public class singleton 雙層檢測鎖 public static singleton getinstance return instanc...

單例模式的幾種寫法

所謂單例模式就是確保某乙個類只有乙個例項,並且提供乙個全域性訪問點。例如 執行緒池 快取 對話方塊等等 1 餓漢模式 保證執行緒安全 public class singleton public static singleton getinstance 2 懶漢模式 不保證執行緒安全 public c...

單例模式的幾種寫法

1.懶漢式 public class singleinstance1 private static singleinstance1 instance public static singleinstance1 getinstance return instance 該程式缺點是執行緒不安全 publ...