45. sync.Mutex 互斥和互斥鎖

channel 在 goroutine 中互相通信是非常合適且方便的送膳。如果,我們不需要互相通信,只需要保證同一時刻只能有一個 goroutine 訪問共享變量惰瓜,以免沖突。我們該怎么做呢汉矿?
這就需要用到 互斥和互斥鎖崎坊。
go 語言標(biāo)準(zhǔn)庫中提供了 sync.Mutex 類型及兩個方法: Lock 和 Unlock
我們可以通過在代碼前加 Lock,在代碼后加 Unlock 的方法洲拇,保證代碼執(zhí)行時的互斥性奈揍。

    c.mux.Lock()    
    c.v[key]++      //Lock之后曲尸,同一時刻只有一個 goroutine 能訪問 c.v
    c.mux.Unlock()

也可以用 defer 語句來保證互斥鎖一定會被解鎖。

    c.mux.Lock()
    defer c.mux.Unlock()

創(chuàng)建一個代碼示例男翰,先建立一個計數(shù)器結(jié)構(gòu)體

//安全計數(shù)器另患,使用 sync.Mutex 保證安全
type SafeCounter struct {
    v map[string]int
    mux sync.Mutex
}

v 是計數(shù)器map,再加上一個 sync.Mutex 類型蛾绎。
給 SafeCounter 增加兩個方法昆箕,一個 inc 來實現(xiàn)計數(shù)器值累加,一個 Value 來實現(xiàn)取得當(dāng)前計數(shù)器值租冠。

//增加計數(shù)器 key 的計數(shù)值
func (c *SafeCounter) Inc(key string)  {
    c.mux.Lock()
    //Lock之后鹏倘,同一時刻只有一個 goroutine 能訪問 c.v
    c.v[key]++
    c.mux.Unlock()
}
//取得計數(shù)器當(dāng)前值
func (c *SafeCounter) Value(key string) int {
    c.mux.Lock()
    defer c.mux.Unlock()
    return c.v[key]
}

主函數(shù)循環(huán) 100 次,使用 goroutine 讓一個計數(shù)器去增加值顽爹。然后取得當(dāng)前計數(shù)器的值纤泵。
為了避免運行太快,看不到效果话原,每次循環(huán)要間隔 100 毫秒夕吻。

time.Sleep(100*time.Millisecond)

完整代碼示例

package main

import (
    "sync"
    "fmt"
    "time"
)

//安全計數(shù)器,使用 sync.Mutex 保證安全
type SafeCounter struct {
    v map[string]int
    mux sync.Mutex
}

//增加計數(shù)器 key 的計數(shù)值
func (c *SafeCounter) Inc(key string)  {
    c.mux.Lock()
    //Lock之后繁仁,同一時刻只有一個 goroutine 能訪問 c.v
    c.v[key]++
    c.mux.Unlock()
}

//取得計數(shù)器當(dāng)前值
func (c *SafeCounter) Value(key string) int {
    c.mux.Lock()
    defer c.mux.Unlock()
    return c.v[key]
}
func main() {
    c := SafeCounter{v:make(map[string]int)}
    for i := 0; i < 100; i++{
        go c.Inc("somekey")
        time.Sleep(100*time.Millisecond)
        fmt.Println(c.Value("somekey"))
    }
    fmt.Println(c.Value("somekey"))
}

運行結(jié)果太長涉馅,不做展示。請自行實踐黄虱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末稚矿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子捻浦,更是在濱河造成了極大的恐慌晤揣,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朱灿,死亡現(xiàn)場離奇詭異昧识,居然都是意外死亡,警方通過查閱死者的電腦和手機盗扒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門跪楞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人侣灶,你說我怎么就攤上這事甸祭。” “怎么了褥影?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵池户,是天一觀的道長。 經(jīng)常有香客問我,道長校焦,這世上最難降的妖魔是什么赊抖? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮寨典,結(jié)果婚禮上熏迹,老公的妹妹穿的比我還像新娘。我一直安慰自己凝赛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布坛缕。 她就那樣靜靜地躺著墓猎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赚楚。 梳的紋絲不亂的頭發(fā)上毙沾,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音宠页,去河邊找鬼左胞。 笑死,一個胖子當(dāng)著我的面吹牛举户,可吹牛的內(nèi)容都是我干的烤宙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼俭嘁,長吁一口氣:“原來是場噩夢啊……” “哼躺枕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起供填,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拐云,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后近她,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叉瘩,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年粘捎,在試婚紗的時候發(fā)現(xiàn)自己被綠了薇缅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡晌端,死狀恐怖捅暴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情咧纠,我是刑警寧澤蓬痒,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站漆羔,受9級特大地震影響梧奢,放射性物質(zhì)發(fā)生泄漏狱掂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一亲轨、第九天 我趴在偏房一處隱蔽的房頂上張望趋惨。 院中可真熱鬧,春花似錦惦蚊、人聲如沸器虾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兆沙。三九已至,卻和暖如春莉掂,著一層夾襖步出監(jiān)牢的瞬間葛圃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工憎妙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留库正,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓厘唾,卻偏偏與公主長得像褥符,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子阅嘶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容