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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

【设计模式】实现线程安全单例模式的五种方式

發布時間:2023/12/10 asp.net 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【设计模式】实现线程安全单例模式的五种方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python微信訂餐小程序課程視頻

https://edu.csdn.net/course/detail/36074

Python實戰量化交易理財系統

https://edu.csdn.net/course/detail/35475

餓漢式

餓漢式:類加載就會導致該單實例對象被創建

復制代碼
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

java`// 問題1:為什么加 final
// 問題2:如果實現了序列化接口, 還要做什么來防止反序列化破壞單例
public final class Singleton_hungry implements Serializable {

// 問題3:為什么設置為私有? 是否能防止反射創建新的實例?
private Singleton_hungry(){}

// 問題4:這樣初始化是否能保證單例對象創建時的線程安全?
private static Singleton_hungry INSTANCE = new Singleton_hungry();

// 問題5:為什么提供靜態方法而不是直接將 INSTANCE 設置為 public, 說出你知道的理由
public static Singleton_hungry getInstance() {
return INSTANCE;
}
public Object readResolve(){ // 防止反射創建新的實例?
return INSTANCE;
}
}`

  • 問題1:
    避免子類覆蓋父類的一些方法,導致線程不安全。
  • 問題2:
    實現 readResolve 方法。當從對象流 ObjectInputStream 中讀取對象時,會檢查對象的類否定義了 readResolve 方法。如果定義了,則調用它返回我們想指定的對象(這里就指定了返回單例對象)。
  • 問題3:防止通過 new 創建對象實例。不能防止反射創建新的實例。
  • 問題4:可以。靜態變量初始化在類加載時進行,由 jvm 進行管理,可以保證線程安全。
  • 問題5:通過方法,可以提高拓展性,改進餓漢式轉化為懶漢式、利用泛型特性、增加對單例對象的控制操作。

枚舉單例

復制代碼
  • 1
  • 2
  • 3

javaenum Singleton { INSTANCE; }

  • 問題1:枚舉單例是如何限制實例個數的
    單例相當于枚舉的靜態成員變量,定義幾個就有幾個實例。
  • 問題2:枚舉單例在創建時是否有并發問題
    單例相當于枚舉的靜態成員變量,類加載時初始化,由 jvm 進行管理,可以保證線程安全。
  • 問題3:枚舉單例能否被反射破壞單例
    不能
  • 問題4:枚舉單例能否被反序列化破壞單例
    枚舉實現了 Serializable 接口,可序列化,但不會被反序列破壞單例。
  • 問題5:枚舉單例屬于懶漢式還是餓漢式
    餓漢式
  • 問題6:枚舉單例如果希望加入一些單例創建時的初始化邏輯該如何做
    枚舉允許構造方法

懶漢式

復制代碼
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

typescriptpublic final class Singleton\_lazy { private Singleton\_lazy(){} private static Singleton_lazy INSTANCE = null; // 缺點 public static synchronized Singleton_lazy getInstance() { if(INSTANCE != null) { return INSTANCE; } INSTANCE = new Singleton_lazy(); return INSTANCE; } }

  • synchronized 保證線程安全,但鎖粒度較大,性能低。

DCL 懶漢式

復制代碼
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

java`public final class Singleton_DCL {

private Singleton_DCL() {}

// 問題1:解釋為什么要加 volatile ?
private static volatile Singleton_DCL INSTANCE= null;

// 問題2:對比實現3, 說出這樣做的意義
public static Singleton_DCL getInstance() {
if(INSTANCE != null) {
return INSTANCE;
}
synchronized (Singleton_DCL.class) {

// 問題3:為什么還要在這里加為空判斷, 之前不是判斷過了嗎
if(INSTANCE != null) {
return INSTANCE;
}
INSTANCE = new Singleton_DCL();
return INSTANCE;
}
}
}`

  • 問題1:避免指令重排序,導致賦值語句先于構造函數執行,得到一個未初始化完畢的對象。
  • 問題2、3:Double Check Lock 機制。同步代碼塊外部的判斷語句主要用于 INSTANCE 初始化并賦值之后,此時 INSTANCE != null,如果有多個線程嘗試獲取單例,可以提前返回,不用執行同步代碼塊。而同步代碼塊內部的判斷主要用于第一次初始化時,INSTANCE = null,此時可以有多個線程嘗試獲取 INSTANCE,只能有一個線程進入同步代碼塊,其他線程在同步代碼塊外阻塞,該線程創建一個單例對象之后,喚醒其他線程,再進入同步代碼塊,發現 INSTANCE != null,則直接返回,不用重新創建單例對象,提高了效率。

靜態內部類懶漢單例

復制代碼
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

java`public final class Singleton_LazyHolder {
private Singleton_LazyHolder(){}

// 問題1:屬于懶漢式還是餓漢式
private static class LazyHolder{
static final Singleton_LazyHolder INSTANCE = new Singleton_LazyHolder();
}

// 問題2:在創建時是否有并發問題
public static Singleton_LazyHolder getInstance() {
return LazyHolder.INSTANCE;
}
}`

  • 問題1:懶漢式。靜態內部類只有在被方法調用的時候才進行初始化,類加載。
  • 問題2:無,類加載由 jvm 進行,線程安全。

總結

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

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