日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

详解单例模式线程安全

發布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详解单例模式线程安全 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

詳解單例模式線程安全

單例模式有很多實現方法,餓漢、懶漢、靜態內部類、枚舉類,每種實現下獲取單例對象(即調用 getInstance)時的保證線程安全

  • 餓漢式:類加載就會導致該單實例對象被創建
  • 懶漢式:類加載不會導致該單實例對象被創建,而是首次使用該對象時才會創建

實現1: 餓漢式

// 問題1:為什么加 final,防止子類繼承后更改 // 問題2:如果實現了序列化接口, 還要做什么來防止反序列化破壞單例,如果進行反序列化的時候會生成新的對象,這樣跟單例模式生成的對象是不同的。要解決直接加上readResolve()方法就行了,如下所示 public final class Singleton implements Serializable {// 問題3:為什么設置為私有? 放棄其它類中使用new生成新的實例,是否能防止反射創建新的實例?不能。private Singleton() {}// 問題4:這樣初始化是否能保證單例對象創建時的線程安全?沒有,這是類變量,是jvm在類加載階段就進行了初始化,jvm保證了此操作的線程安全性private static final Singleton INSTANCE = new Singleton();// 問題5:為什么提供靜態方法而不是直接將 INSTANCE 設置為 public, 說出你知道的理由。//1.提供更好的封裝性;2.提供范型的支持public static Singleton getInstance() {return INSTANCE;}public Object readResolve() {return INSTANCE;} }

實現2: 餓漢式

// 問題1:枚舉單例是如何限制實例個數的:創建枚舉類的時候就已經定義好了,每個枚舉常量其實就是枚舉類的一個靜態成員變量 // 問題2:枚舉單例在創建時是否有并發問題:沒有,這是靜態成員變量 // 問題3:枚舉單例能否被反射破壞單例:不能 // 問題4:枚舉單例能否被反序列化破壞單例:枚舉類默認實現了序列化接口,枚舉類已經考慮到此問題,無需擔心破壞單例 // 問題5:枚舉單例屬于懶漢式還是餓漢式:餓漢式 // 問題6:枚舉單例如果希望加入一些單例創建時的初始化邏輯該如何做:加構造方法就行了 enum Singleton {INSTANCE; }

實現3:懶漢式

public final class Singleton {private Singleton() { }private static Singleton INSTANCE = null;// 分析這里的線程安全, 并說明有什么缺點:synchronized加載靜態方法上,可以保證線程安全。缺點就是鎖的范圍過大,每次訪問都會加鎖,性能比較低。public static synchronized Singleton getInstance() {if( INSTANCE != null ){return INSTANCE;}INSTANCE = new Singleton();return INSTANCE;} }

實現4:DCL 懶漢式(雙重檢驗鎖)

public final class Singleton {private Singleton() { }// 問題1:解釋為什么要加 volatile ?為了防止重排序問題private static volatile Singleton INSTANCE = null;// 問題2:對比實現3, 說出這樣做的意義:提高了效率public static Singleton getInstance() {if (INSTANCE != null) {return INSTANCE;}synchronized (Singleton.class) {// 問題3:為什么還要在這里加為空判斷, 之前不是判斷過了嗎?這是為了第一次判斷時的并發問題。if (INSTANCE != null) { // t2return INSTANCE;}INSTANCE = new Singleton();return INSTANCE;}} }

實現5:靜態內部類懶漢式

public final class Singleton {private Singleton() { }// 問題1:屬于懶漢式還是餓漢式:懶漢式,這是一個靜態內部類。類加載本身就是懶惰的,在沒有調用getInstance方法時是沒有執行LazyHolder內部類的類加載操作的。private static class LazyHolder {static final Singleton INSTANCE = new Singleton();}// 問題2:在創建時是否有并發問題,這是線程安全的,類加載時,jvm保證類加載操作的線程安全public static Singleton getInstance() {return LazyHolder.INSTANCE;} }

總結

以上是生活随笔為你收集整理的详解单例模式线程安全的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。