網站首頁 編程語言 正文
在go里實現單例模式有多種方式:
- 基于lock
- 基于init函數
- 基于sync.Once
本文介紹基于sync.Once的方式來實現單例,熟練掌握這種模式,并理解其底層原理,對大部分人來講已經完全夠用了。
基于sync.Once實現單例
// 其他package也可見,在其他地方也可以new新對象 // 但是最終調用Conn()方法時,都是用的single這個單例 // 1 type Driver struct { // 小寫字母開頭,外部不可訪問,所以new個Driver新對象也沒用 // 2 conn string } // 全局變量,指針默認值為nil // 3 var single *Driver // 單例 var once sync.Once // 對外暴露的公共方法 func (s *Driver) Conn() { fmt.Printf("conn=%s", single.conn) // do something } // 4 func GetDriverSingleton() *Driver { // 對GetDriverSingleton()方法的調用,都會執行once.Do()方法,只不過參數func()只會被執行一次 // 若并發執行once.Do(),多個協程會阻塞,因內部是通過Mutex來控制 once.Do(func() { single = new(Driver) single.conn = "single conn" time.Sleep(50 * time.Millisecond) }) return single }
單例類型定義Driver
Driver類的方法要支持跨包訪問,因此需要以大寫字母開頭。
小寫字母開頭,作用域僅限于包內部。
類Field conn
類變量conn需要小寫字母開頭,跨包不可訪問,避免在包外被修改。
但是包內還是有可能被修改。
once.Do(func() {})
每次調用GetDriverSingleton(),都會調用once.Do()方法,但是在once.Do()方法內部,僅會執行一次參數func(){},因此就保證了單例唯一初始化。
并發訪問once.Do()
不會有并發訪問問題,因once.Do()內部通過mutex來控制。
// once.DO() if atomic.LoadUint32(&o.done) == 0 { // Outlined slow-path to allow inlining of the fast-path. o.doSlow(f) } // doSlow() func (o *Once) doSlow(f func()) { o.m.Lock() // 互斥鎖 defer o.m.Unlock() if o.done == 0 { defer atomic.StoreUint32(&o.done, 1) f() } }
對外暴露方法Conn()
外部對Conn()方法的調用,最終都由單例single來實現。
重新new(Driver)會發生什么?
很遺憾,無法將構造函數改成private,也就是說,在包外部是可以通過new(Driver)來創建新的對象。
但無論是哪個對象,對公開方法Conn()的調用,最終都是由單例single來執行的。
原文鏈接:https://blog.csdn.net/hugo_lei/article/details/127537614
相關推薦
- 2022-07-16 借助Redis的過期機制和分布式鎖實現定時任務
- 2022-05-12 centos7.6升級glibcln: relocation error: /lib64/libc
- 2023-07-07 Tomcat文件夾屬性
- 2022-11-20 解析在Tomcat中啟用虛擬線程特性_Tomcat
- 2022-07-30 Python?excel合并居中值相同的單元格實例代碼_python
- 2022-07-08 C#四種計時器Timer的區別和用法_C#教程
- 2022-02-11 tomcat?logs?目錄下各日志文件的解析(小結)_Tomcat
- 2022-01-30 tortoisegit pull時報錯
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支