偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

簡單的單例模式,Go版本的實現(xiàn)你寫對了嗎?

開發(fā) 前端
由于要控制數(shù)量,那么可想而之只能把實例的訪問進行收口,不能誰來了都能 new 一個出來,所以單例模式還會提供一個訪問該實例的全局端口,一般都會命名個 GetInstance之類的函數(shù)用作實例訪問的端口。

大家好,我是網(wǎng)管,首先我問大家一個問題,你們面試的時候,面試官有沒有問過你們:"你都用過什么設計模式?",我猜多數(shù)人的回答會把單例模式,放在第一位。

我:"呃… 我用過單例、工廠、觀察者,反向代理,裝飾器,哨兵"…. ",

面試官內(nèi)心OS:"我都沒用過這么多...反向代理是什么鬼,這小子背串了吧,不管了先就坡下驢,從頭開始問"。

面試官:"用過的挺多哈,那么你能說下單例你都在什么情況下用,順便在這張紙上實現(xiàn)一下單例吧"。

我:"當需要確保一個類型,只有一個實例時就需要使用單例模式了"。

面試官:"好,那你在紙上實現(xiàn)一下"

十分鐘后的我:"不好意思,我們之前項目里都封裝好了,我只用過,沒有機會實現(xiàn),所以..."

面試官內(nèi)心OS:"好吧,這個面試KPI要求得進行三十分鐘,這還有小二十分鐘呢,隨便再問問,就讓他回去等信兒吧"

面試卒...

上面是我給大家編的一個場景,如有雷同,請憋住,不要在工位上笑噴~。單例模式雖然簡單,不過還是有一些說道兒的,一是應用比較廣泛,再來如果不注意容易在多線程環(huán)境下造成BUG,今天就給大家簡單說下單例模式的應用,以及用Go語言怎么正確地實現(xiàn)單例模式。

單例模式

上面對話里說的沒錯,單例模式是用來控制類型實例的數(shù)量的,當需要確保一個類型只有一個實例時,就需要使用單例模式。

由于要控制數(shù)量,那么可想而之只能把實例的訪問進行收口,不能誰來了都能 new 一個出來,所以單例模式還會提供一個訪問該實例的全局端口,一般都會命名個 GetInstance之類的函數(shù)用作實例訪問的端口。

又因為在什么時間創(chuàng)建出實例,單例模式又可以分裂出餓漢模式? 和 懶漢模式,前者適用于在程序早期初始化時創(chuàng)建已經(jīng)確定需要加載的類型實例,比如項目的數(shù)據(jù)庫實例。后者其實就是延遲加載的模式,適合程序執(zhí)行過程中條件成立才創(chuàng)建加載的類型實例。

下面我們用 Go 代碼把這兩種單例模式實現(xiàn)一下。

餓漢模式

這個模式用 Go 語言實現(xiàn)時,借助 Go 的init函數(shù)來實現(xiàn)特別方便

如果你想了解 Go init 函數(shù)的方方面面,可以看以前的老文章Go語言init函數(shù)你必須記住的六個特征

下面用單例模式返回數(shù)據(jù)庫連接實例,相信你們在項目里都見過類似代碼。

package dao
// 餓漢式單例
// 注意定義非導出類型
type databaseConn struct{
...
}

var dbConn *databaseConn

func init() {
dbConn = &databaseConn{}
}

// GetInstance 獲取實例
func Db() *databaseConn {
return dbConn
}

這里初始化數(shù)據(jù)庫的細節(jié)咱們就不多費文筆了,實際情況肯定是從配置中心加載下來數(shù)據(jù)庫連接配置再實例化數(shù)據(jù)庫的連接對象。這里有人可能會有個問題,你這一個程序進程就只有一個數(shù)據(jù)連接實例,那這么多請求都用一個數(shù)據(jù)庫連接行嗎?

誒,這個是對數(shù)據(jù)庫連接的抽象呀,這個實例會維護一個連接池,那里才是真正去請求數(shù)據(jù)庫用的連接。是不是有點暈,有點暈去看看你們項目里這塊的代碼。一般會看到初始化實例時,讓你設置最大連接數(shù)、閑置連接數(shù)和存活時間這樣的連接池配置。

懶漢模式

懶漢模式--通俗點說就是延遲加載,不過這塊特別注意,要考慮并發(fā)環(huán)境下,你的判斷實例是否已經(jīng)創(chuàng)建時,是不是用的當前讀。在一些教設計模式的教程里,一般這種情況下會舉一個例子--用 Java 雙重鎖實現(xiàn)線程安全的單例模式,雙重鎖指的是volatile和synchronized。

class Singleton {
private volatile static Singleton instance = null;

private Singleton() {}

public static Singleton getInstance() {
if(instance==null) {
synchronized (Singleton.class) {
if(instance==null)
instance = new Singleton();
}
}
return instance;
}
}

上面這個例子里,如果不給instance?屬性加上 volatile?修飾符,那么雖說創(chuàng)建的過程已經(jīng)用synchronized?給類加了鎖,但是有可能讀到的instance?是線程緩存是滯后的,有可能屬性此時已經(jīng)被其他線程初始化了,所以就必須加上volatile保證當前讀(讀主存里屬性的狀態(tài))。

那么 Go 里邊沒有volatile?這種機制,我們該怎么辦呢?聰明的你一定能想得出,我們定義一個實例的狀態(tài)變量,然后用原子操作atomic.Load、atomic.Store去讀寫這個狀態(tài)變量,不就是實現(xiàn)了嗎?像下面這樣:

如果 Go 原子操作你還不熟,請看老文章Golang 五種原子性操作的用法詳解

import "sync"
import "sync/atomic"

var initialized uint32

type singleton struct {
...
}

func GetInstance() *singleton {

if atomic.LoadUInt32(&initialized) == 1 { // 原子操作
return instance
}

mu.Lock()
defer mu.Unlock()

if initialized == 0 {
instance = &singleton{}
atomic.StoreUint32(&initialized, 1)
}

return instance
}

確實,相當于把上面 Java 的例子翻譯成用 Go 實現(xiàn)了,不過還有另外一種更Go? native 的寫法,比這種寫法更簡練。如果用 Go 更慣用的寫法,我們可以借助其sync?庫中自帶的并發(fā)同步原語Once來實現(xiàn):

package singleton

import (
"sync"
)

type singleton struct {}

var instance *singleton
var once sync.Once

func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}

關于sync.One ?的使用和其實現(xiàn)原理…我發(fā)現(xiàn)我的Go 并發(fā)編程系列?里沒單獨寫Once?這個原語,可能是覺得太簡單了吧,后期抽空補上吧… 不過只是原理分析沒寫,怎么應用在Go語言sync包的應用詳解里也能找到。

總結(jié)

這篇文章其實是把單例模式的應用,和Go的單例模式版本怎么實現(xiàn)給大家說了一下,現(xiàn)在教程大部分都是用 Java 講設計模式的,雖然我們可以直接翻譯,不過有的時候 Go 有些更native 的實現(xiàn)方式,讓實現(xiàn)更簡約一些。

責任編輯:武曉燕 來源: 網(wǎng)管叨bi叨
相關推薦

2024-11-06 11:38:59

C#單例模式

2018-04-03 15:38:07

Java單例模式模式設計

2017-11-09 13:56:46

數(shù)據(jù)庫MongoDB水平擴展

2020-09-18 06:39:18

hashMap循環(huán)數(shù)據(jù)

2021-11-02 22:04:58

模式

2020-12-17 08:56:51

單例模式JVM

2023-12-05 08:20:05

單例模式Python

2020-09-16 12:18:28

GoJava模式

2013-03-26 10:35:47

Objective-C單例實現(xiàn)

2022-08-10 11:02:56

Python單例模式

2025-06-20 09:57:42

2022-02-06 22:30:36

前端設計模式

2021-09-07 10:44:35

異步單例模式

2024-12-17 15:00:00

字符串Java

2019-12-26 14:07:19

隨機數(shù)偽隨機多線程

2011-06-28 15:18:45

Qt 單例模式

2020-08-04 08:37:23

Kafka分區(qū)數(shù)

2024-03-06 13:19:19

工廠模式Python函數(shù)

2021-10-19 08:20:47

單例模式設計模式面試
點贊
收藏

51CTO技術(shù)棧公眾號