golang創建式設計模式------單例模式

目錄導航

      • 1.單例模式
        • 1)什么是單例模式
      • 2)使用場景
      • 3)實現方式
        • 1.懶漢式單例模式
        • 2.餓漢式
        • 3.雙重檢查式
        • 4.`sysc.Once`式
      • 4)實踐案例
      • 5)優缺點分析

1.單例模式

1)什么是單例模式

單例模式(Singleton Pattern)是一種常用的設計模式。單例模式的類提供了一種訪問其唯一對象的方法,該對象可以直接訪問,無須實例化。單例模式保證了一個類的對象只存在一個,同時維護一個對其對象的全局訪問點。

uml類圖:

在這里插入圖片描述

2)使用場景

  • 如果開發者想要更加嚴格地控制全局變量,則可以使用單例模式。單例模式可以保證一個類只存在一個實例。除了單例模式外,無法通過其他方式替換緩存的實例
  • 如果程序中的某個類對于所有客戶端都只有一個可用的實例,則可以使用單例模式。在單例模式中,如果對象已經被創建,則返回已有的對象
  • 在設計數據庫連接池時,可以使用單例模式。在數據庫管理系統中使用數據庫連接池,主要目的是節省打開或關閉數據庫連接引起的效率損耗。這種效率上的損耗還是非常巨大的,如果使用單例模式來進行維護的話,則可以大大減少這中類似的損耗。

3)實現方式

在golang中,單例模式的實現方式有4中,分別是懶漢式、餓漢式、雙重檢查式、和sysnc.Once。而這四種單例模式都有一個共同的特征:只實例化一次,只允許一個實例存在。

1.懶漢式單例模式

懶漢式單例模式指的是在創建對象時,不直接創建對象,在加載配置文件時才創建對象。

package typesofSigtonimport "sync"type singleton struct{value int
}
//聲明私有指令
var instance *singleton
//加鎖的目的是保證協成并發安全
//mo1.聲明鎖對象
var mutex sync.Mutex
//獲取單例對象
func GetInstance() *singleton {//加鎖,保證協成安全mutex.Lock()defer mutex.Unlock()if instance==nil{instance=new (singleton)}return instance
}

以上代碼通過加鎖的方式保證了協成的并發安全但是代碼有一個問題就是每次調用該方法都需要進行加鎖的操作,在性能上則不夠高效。

2.餓漢式

餓漢式是指,在創建對象時,不判斷創建的對象是否為空,直接創建對象。餓漢式是并發安全的,其唯一的缺點是在導入包的同時會創建對象,并且創建的對象會持續存儲于內存當中。餓漢式單例模式可以使用初始化init()函數實現

package typesofSigtonimport "fmt"//var instance *singleton
func init(){if instance==nil{instance=new(singleton)fmt.Println("創建單個實例")}
}//編寫提供實力的函數
func GetInstance() *singleton {return instance
}
3.雙重檢查式

在懶漢式的基礎上進行優化,減少加鎖的操作,這樣可以在保證并發安全的同時不影響性能,這種模式也被稱為雙重檢查單例模式

package typesofSigtonimport ("fmt""sync"
)
//聲明鎖對象
var mutex sync.Mutex
//當對象為空時,對對象進行加鎖操作;在創建好對象后,在獲取對象時就不用加鎖了
func GetIntance() *singleton{if instance ==nil{mutex.Lock()if instance==nil{instance=new(singleton)fmt.Println("創建單個實例")}mutex.Unlock()}return instance
}
4.sysc.Once

sysc.Once是go標準庫提供的使函數只執行一次的實現,通常應用于單例模式,如初始化配置、保持數據庫連接等。其作用與init()函數類似,但有區別。init()函數會在其所在的包首次被加載時執行,如果被加載的包不立即被使用,那么既浪費了內存空間,又延長了程序加載時間。

sysc.Once可以在代碼的任意位置被初始化和調用,在并發場景中是并發安全的,使用sysc.Once對象的Do()方法創建實例,可以確保創建對象的方法只被執行一次

package typesofSigtonimport ("fmt""sync"
)
var once sync.Once
func GetIntance() *singleton{once.Do(func() {instance=new(singleton)fmt.Println("創建單個實例")})return instance
}

4)實踐案例

excample.go

package excampleimport ("fmt""sync"
)var lock = &sync.Mutex{}type singleton struct {
}var instance *singleton// 獲取實例對象
func GetInstance() *singleton {if instance == nil {lock.Lock()defer lock.Unlock()if instance == nil {fmt.Println("創建單個實例")instance = new(singleton)} else {fmt.Println("已創建單個實例")}} else {fmt.Println("已創建單個實例")}return instance
}

main.go

package mainimport ("Signton/excample""fmt"
)func main() {for i := 0; i < 3; i++ {go excample.GetInstance()}fmt.Scanln()
}//運行結果為
//創建單個實例
//已創建單個實例
//已創建單個實例

5)優缺點分析

優點:

  • 單例模式可以擴展為工廠模式。
  • 由于系統的內存中只存在一個對象,因此對于需要頻繁創建和銷毀對象的系統,使用單例模式可以提升系統的性能

缺點:

  • 由于單例模式不是抽象的,因此其擴展性較低
  • 濫用單例模式會產生一些負面問題。例如,為了節省資源,如果使用單例模式設計數據連接池對象,則可能會導致共享連接池對象過多且沒有被釋放的場景,從而出現連接池溢出的問題。此外,如果實例化的對象長時間不被使用,那么他可能會被操作系統認為是垃圾對象而回收,從而導致對象缺失。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11866.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11866.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11866.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RAG系列論文

檢索增強模型&#xff1a; 提出Atlas &#xff1a;預訓練檢索增強模型 Few-shot Learning with Retrieval Augmented Language Models 鏈接 根據輸入問題的不同&#xff0c;挑選合適的提示詞 Learning To Retrieve Prompts for In-Context Learning 鏈接 RAG&#xff1a; M…

【數據結構】線性表--順序表(二)

文章目錄 1、什么是線性表2、線性表的基本操作3、順序表3.1、順序表的定義3.2、順序表的實現方式&#xff1a;靜態分配3.3、順序表的實現方式&#xff1a;動態分配3.4、順序表的特點3.5、順序表的初始化與插入操作3.6、順序表的刪除與查詢 1、什么是線性表 ? 線性表是具有相同…

【Python快速上手(二十二)】

目錄 Python快速上手&#xff08;二十二&#xff09;Python3 使用數據庫-pymysql1. 創建數據庫連接2. 創建數據表3. 插入數據4. 查詢數據5. 使用 WHERE 條件語句6. 排序7. 刪除記錄8. 更新表數據9. 刪除表10.異常處理總結 Python快速上手&#xff08;二十二&#xff09; Pytho…

通過EXCEL控制PLC啟停電機的一種方法

概述 本例將介紹用微軟EXCEL電子表格控制西門子S7-1200 PLC實現電機啟停的一種方法。 第1步&#xff1a; 添加PLC設備&#xff0c;選擇西門子S7-1214C CPU&#xff0c;設置IP地址&#xff1a;192.168.18.18&#xff0c;子網掩碼&#xff1a;255.255.255.0。 第2步&#xff1a…

vue3中通過自定義指令實現loading加載效果

前言 在現代Web開發中&#xff0c;提升用戶體驗一直是開發者們追求的目標之一。其中&#xff0c;一個常見的場景就是在用戶與應用程序進行交互時&#xff0c;特別是當進行異步操作時&#xff08;如網絡請求&#xff09;&#xff0c;為用戶提供即時的反饋&#xff0c;避免用戶因…

Flet初體驗:Python跨平臺開發新選擇

文章目錄 ?? 介紹 ???? 演示環境 ???? 初識Flet ???? 安裝與配置?? 構建第一個Flet應用?? Flet打包:跨平臺的魔法?? Flet與FastAPI的結合?? 總結?? 相關鏈接 ???? 介紹 ?? “探索未知,擁抱創新,Flet讓我在應用開發的世界中找到了新的航標。”…

02 | 該如何選擇消息隊列?

RabbitMQ RabbitMQ 一個比較有特色的功能是支持非常靈活的路由配置&#xff0c;和其他消息隊列不同的是&#xff0c;它在生產者&#xff08;Producer&#xff09;和隊列&#xff08;Queue&#xff09;之間增加了一個 Exchange 模塊&#xff0c;你可以理解為交換機。 問題 Ra…

【循環程序設計-譚浩強適配】(適合專升本、考研)

無償分享學習資料&#xff0c;需要的小伙伴評論區或私信dd。。。 無償分享學習資料&#xff0c;需要的小伙伴評論區或私信dd。。。 無償分享學習資料&#xff0c;需要的小伙伴評論區或私信dd。。。 完整資料如下&#xff1a;純干貨、純干貨、純干貨&#xff01;&#xff01;…

淺談電動汽車充電站的電氣安全

1 引言 1月14日日上午10點左右&#xff0c;青島市市北區遼寧路63號公交停車場內&#xff0c;一輛報廢公交車突然起火&#xff0c;由于大風天氣&#xff0c;大火很快引燃了停在旁邊的幾輛報廢車。消防人員快速趕到&#xff0c;迅速控制住火勢。11時30分&#xff0c;停車場內的…

鴻蒙內核源碼分析(ELF格式篇) | 應用程序入口并不是main

閱讀之前的說明 先說明&#xff0c;本篇很長&#xff0c;也很枯燥&#xff0c;若不是絕對的技術偏執狂是看不下去的.將通過一段簡單代碼去跟蹤編譯成ELF格式后的內容.看看ELF究竟長了怎樣的一副花花腸子&#xff0c;用readelf命令去窺視ELF的全貌&#xff0c;最后用objdump命令…

Image to Music V2 :只需上傳一張照片,自動轉換成與圖片內容匹配的音頻!

前言 我們之前肯定已經見過了很多文本生成圖片、文本生成聲音以及AI翻唱歌曲 等多種AI產品&#xff08;模型&#xff09;。 其實音樂和圖片從某種意義上來說都是藝術創作的一種形式&#xff0c;它們可以相互配合&#xff0c;共同呈現出一種更加豐富、感性的表達方式。 將圖片…

弘君資本:人形機器人概念走強,盛通股份漲停,怡合達、鼎智科技等拉升

人形機器人概念14日盤中拉升走高&#xff0c;到發稿&#xff0c;盛通股份漲停&#xff0c;怡合達、鼎智科技漲約6%&#xff0c;索辰科技、偉創電氣、豐立智能等漲超4%。 音訊面上&#xff0c;5月13日&#xff0c;宇樹發布人形智能體Unitree G1&#xff0c;身高127cm,體重35kg&…

[240514] OpenAI 發布 GPT-4o,人機交互的歷史性時刻 | 蘋果芯片進軍服務器劍指AI? | 谷歌大會以AI為主

目錄 OpenAI 發布 GPT-4o&#xff0c;人機交互的歷史時刻蘋果芯片進軍服務器&#xff0c;劍指生成式 AI2024年谷歌開發者大會將圍繞 AI 展開 OpenAI 發布 GPT-4o&#xff0c;人機交互的歷史時刻 OpenAI 發布了 GPT-4o&#xff0c;大家一直都想要現在終于等到的語音助手 : 勿需…

618值得入手的數碼產品怎么選?2024 買過不后悔的數碼好物分享

在數字時代的浪潮中&#xff0c;每一次的購物狂歡節都如同一場科技盛宴&#xff0c;讓我們有機會接觸到最前沿、最實用的數碼產品&#xff0c;而“618”無疑是這場盛宴中最為引人矚目的日子之一。面對琳瑯滿目的商品&#xff0c;如何選擇那些真正值得入手的數碼好物&#xff0c…

易寶OA-ExecuteQueryForDataSetBinary處sql注入

免責聲明&#xff1a; 本文內容為學習筆記分享&#xff0c;僅供技術學習參考&#xff0c;請勿用作違法用途&#xff0c;任何個人和組織利用此文所提供的信息而造成的直接或間接后果和損失&#xff0c;均由使用者本人負責&#xff0c;與作者無關&#xff01;&#xff01;&#…

Centos 安裝jenkins 多分支流水線部署前后端項目

1、安裝jenkins 1.1 安裝jdk 要求&#xff1a;11及以上版本 yum install yum install java-11-openjdk 1.2 安裝jenkins 導入鏡像 sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo出現以下錯誤 執行以下命令 sudo yum …

前端使用原生JS怎么上傳本地路徑的文件到后端【附源碼】

本文不使用<input type"file">等前端上傳組件 一、為什么不能使用本地文件路徑上傳&#xff1f; 前端不能直接根據本地文件路徑&#xff08;例如 C:\Users\Username\Documents\image.jpg&#xff09;上傳文件到后端服務器&#xff0c;原因主要在于瀏覽器的安全…

使用java遠程提交flink任務到yarn集群

使用java遠程提交flink任務到yarn集群 背景 由于業務需要&#xff0c;使用命令行的方式提交flink任務比較麻煩&#xff0c;要么將后端任務部署到大數據集群&#xff0c;要么弄一個提交機&#xff0c;感覺都不是很離線。經過一些調研&#xff0c;發現可以實現遠程的任務發布。…

LOTO示波器軟件PC緩存(波形錄制與回放)功能

當打開PC緩存功能后, 軟件將采用先進先出的原則排隊對示波器采集的每一幀數據, 進行幀緩存。 當發現屏幕中有感興趣的波形掠過時, 鼠標點擊軟件的(暫停)按鈕, 可以選擇回看某一幀的波形。一幀數據的量 是 當前用戶選擇時基檔位緩沖區總數據大小。不同時基檔位緩沖區大小不同&am…

談談std::map的lower_bound

我們知道std::map內部是一個紅黑樹&#xff0c;放到std::map里的數據等有一個能比較大小的方法。它相當于java里面的TreeMap。 它里面有個lower_bound方法&#xff0c;返回一個迭代器&#xff0c;它指向map里第一個大于等于參數的元素。 方法的簽名很簡單&#xff0c;但是在不同…