多線程讀寫共享變量的幾種處理模式

將共享變量的讀寫放到一個(gè) goroutine 中,其它 goroutine 通過(guò) channel 進(jìn)行讀寫操作所坯,這種方式有很多好處钦讳。

package bank

var deposits = make(chan int) // send amout to deposit
var balances = make(chan int) // receive balance

func Deposit(amount int) {
    deposits <- amount
}

func Balance() int {
    return <-balances
}

func teller() {
    var balance int // balance 只在 teller 中可以訪問(wèn)
    for {
        select {
        case amount := <-deposits:
            balance += amount
        case balances <- balance:
        }
    }
}

func init() {
    go teller()
}

第二種就是最常見(jiàn)的互斥了银室,共享變量要互斥訪問(wèn)
可以用個(gè)數(shù)為 1 的信號(hào)量(semaphore)實(shí)現(xiàn)互斥

var (
    sema    = make(chan struct{}, 1)
    balance int
)

func Deposit(amout int) {
    sema <- struct{}{} // acquire token
    balance = balance + amout
    <-sema // release token
}

func Balance() int {
    sema <- struct{}{} // acquire token
    b := balance
    <-sema // release token
    return b
}

go 內(nèi)部提供了互斥操作

import "sync"

var (
    mu      sync.Mutex
    balance int
)

func Deposit(amount int) {
    mu.Lock()
    defer mu.Unlock()
    balance = balance + amount
}

func Balance() int {
    mu.Lock()
    defer mu.Unlock()
    return balance
}

為什么 Balance 也需要互斥,多線程同時(shí)讀取一個(gè)變量有問(wèn)題嗎稻轨?灵莲?? Balance 也需要互斥是為了防止在寫的過(guò)程中進(jìn)行讀取殴俱。如果在讀的過(guò)程中沒(méi)有線程在寫多線程同時(shí)讀取是沒(méi)有問(wèn)題的政冻。所以為了提高讀取的并發(fā)量可以用讀寫鎖改寫

var mu sync.RWMutex
var balance int
 func Balance() int {
     mu.RLock() // readers lock
     defer mu.RUnlock()
     return balance
}

Deposit 不變,Balance 只獲取 RLock 讀鎖线欲,只要沒(méi)有線程在寫明场,多個(gè)線程可同時(shí)獲得 RLock 鎖。

Do not communicate by sharing memory. Instead, share memory by communicating.

sync 庫(kù)和 channel 的選擇要看場(chǎng)景李丰,哪種更簡(jiǎn)單更適合就用哪種苦锨。大部分場(chǎng)景可用 channel 實(shí)現(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末趴泌,一起剝皮案震驚了整個(gè)濱河市舟舒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌踱讨,老刑警劉巖魏蔗,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異痹筛,居然都是意外死亡莺治,警方通過(guò)查閱死者的電腦和手機(jī)廓鞠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谣旁,“玉大人床佳,你說(shuō)我怎么就攤上這事¢螅” “怎么了砌们?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)搁进。 經(jīng)常有香客問(wèn)我浪感,道長(zhǎng),這世上最難降的妖魔是什么饼问? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任影兽,我火速辦了婚禮,結(jié)果婚禮上莱革,老公的妹妹穿的比我還像新娘峻堰。我一直安慰自己,他們只是感情好盅视,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布捐名。 她就那樣靜靜地躺著,像睡著了一般闹击。 火紅的嫁衣襯著肌膚如雪镶蹋。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天赏半,我揣著相機(jī)與錄音梅忌,去河邊找鬼。 笑死除破,一個(gè)胖子當(dāng)著我的面吹牛牧氮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瑰枫,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼踱葛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了光坝?” 一聲冷哼從身側(cè)響起尸诽,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盯另,沒(méi)想到半個(gè)月后性含,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸳惯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年商蕴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叠萍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绪商,死狀恐怖苛谷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情格郁,我是刑警寧澤腹殿,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站例书,受9級(jí)特大地震影響锣尉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜决采,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一悟耘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧织狐,春花似錦、人聲如沸筏勒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)管行。三九已至厨埋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捐顷,已是汗流浹背荡陷。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迅涮,地道東北人废赞。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像叮姑,于是被迫代替她去往敵國(guó)和親唉地。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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

  • 在上篇中,我們已經(jīng)討論過(guò)如何去實(shí)現(xiàn)一個(gè) Map 了朱盐,并且也討論了諸多優(yōu)化點(diǎn)群嗤。在下篇中,我們將繼續(xù)討論如何實(shí)現(xiàn)一個(gè)線...
    一縷殤流化隱半邊冰霜閱讀 7,600評(píng)論 5 41
  • 引用自多線程編程指南應(yīng)用程序里面多個(gè)線程的存在引發(fā)了多個(gè)執(zhí)行線程安全訪問(wèn)資源的潛在問(wèn)題兵琳。兩個(gè)線程同時(shí)修改同一資源有...
    Mitchell閱讀 1,984評(píng)論 1 7
  • Java8張圖 11狂秘、字符串不變性 12骇径、equals()方法、hashCode()方法的區(qū)別 13赃绊、...
    Miley_MOJIE閱讀 3,697評(píng)論 0 11
  • Java-Review-Note——4.多線程 標(biāo)簽: JavaStudy PS:本來(lái)是分開(kāi)三篇的既峡,后來(lái)想想還是整...
    coder_pig閱讀 1,641評(píng)論 2 17
  • 12月1日 晴 生活在這繁華城市的我們,有著自身獨(dú)特的生存方式碧查,以平和心態(tài)對(duì)待每個(gè)人运敢,或許就有著不同的結(jié)果。
    暖心陽(yáng)閱讀 180評(píng)論 0 0