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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

单件模式(单例模式)

發布時間:2023/12/3 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单件模式(单例模式) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】README 0.1)本文部分描述轉自 “head first 設計模式”, 旨在學習?單件模式(單例模式) 的相關知識 及其應用;
【1】單件模式 1.0)單件模式的應用背景:有一些對象其實我們只需要一個,比方說: 線程池,緩存,對話框,注冊表等的對象,這都可以通過單件模式來解決; 1.1)定義:確保一個類只有一個實例,并提供一個全局訪問點; 1.2)全局變量的缺點:如果將對象賦值給一個全局變量,那么你必須在程序一開始就創建好對象,對吧?萬一這個對象非常耗費資源,而程序在這次的執行過程中又一直沒有用到它,不就形成浪費了嘛?(干貨——使用全局變量可能出現的問題)
【2】剖析經典的單件模式實現 public class Singleton {private static Singleton uniqueInstance;private Singleton() {}public static Singleton getInstance() {if (uniqueInstance == null) {uniqueInstance = new Singleton();}return uniqueInstance;}// other useful methods herepublic String getDescription() {return "I'm a classic Singleton!";} } 對以上的代碼的分析(Analysis): A1)如果該對象不存在,我們就利用私有構造器產生一個 Singleton 實例并把它賦值到 uniqueInstance 靜態變量中。 A2)注意:如果我們不需要這個實例,它就永遠不會產生。這就是“延遲實例化”;(干貨——延遲實例化) A3)看看它的類圖:?getInstance()方法是靜態的,這意味著它是一個類方法,所以可以在代碼的任何地方使用 Singleton.getInstance() 訪問它。這和訪問全局變量一樣簡單,只是多了一個優點: 單件可以延遲實例化;
【3】并發訪問實例方法(處理多線程) 3.0)多線程訪問實例方法所遇到的問題:返回了兩個不同對象object1 和 object2,多線程訪問的細粒度steps 如下所示:
3.1)把 getInstance() 變成同步(synchronized)方法,解決并發問題; public class ConcurrencySingleton {private static ConcurrencySingleton uniqueInstance;private ConcurrencySingleton() {}public static synchronized ConcurrencySingleton getInstance() {if (uniqueInstance == null) {uniqueInstance = new ConcurrencySingleton();}return uniqueInstance;}// other useful methods herepublic String getDescription() {return "I'm a classic Singleton!";} } 3.2)加上 synchronized后的性能問題:顯然,這樣會降低同步的性能,這引入了另一個問題; 問題詳述:這個問題比你想象的還要嚴重,因為只有第一次執行此方法時,才真正需要同步。換句話說,一旦設置好uniqueInstanc 變量, 就不再需要同步這個方法了。之后每次調用這個方法,同步都是一種累贅,顯著地降低了程序性能;(因為當多個線程并發訪問 getInstance 方法的時候,有且只有一個線程能夠獲得同步鎖,訪問方法成功,某個線程訪問成功后,其他線程才有可能去訪問該方法,此時叫串行訪問而不是并行訪問了); 3.3)solution(多線程下的單件模式): s1)如果getInstance() 的性能對應用程序不是很關鍵,就什么也別做;(不用加 synchronized關鍵字); s2)使用 急切創建實例,而不用延遲實例化的做法;(干貨——比較急切實例化和延遲實例化的區別) public class Singleton {private static Singleton uniqueInstance = new Singleton();private Singleton() {}public static Singleton getInstance() {return uniqueInstance;} s3)使用雙重檢查加鎖,在 getInstance()中減少使用同步:利用雙重檢查加鎖,首先檢查是否實例對象已經創建了,如果沒有創建,才進行同步。這樣一來,也就只有第一次才會同步,這正是我們想要的;(干貨——我個人推薦使用這個加鎖機制) public class ConcurrencySingletonV2 {private volatile static ConcurrencySingletonV2 uniqueInstance;private ConcurrencySingletonV2() {}// 只有第一次才執行全部代碼,否則跳轉到 return 語句行public static ConcurrencySingletonV2 getInstance() {if (uniqueInstance == null) { // 第一次檢查 synchronized (ConcurrencySingletonV2.class) {if (uniqueInstance == null) { // 第二次檢查:進入同步塊后,如果實例仍然是null,才創建實例uniqueInstance = new ConcurrencySingletonV2();}}}return uniqueInstance;} }

Attention)Volatile 關鍵字:為實例域的同步訪問提供了一種免鎖機制, 如果說明一個域為 volatile, 那么編譯器和 虛擬機就知道該域是可能被另一個線程并發更新的;


總結

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

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