多线程读写共享变量的几种处理模式

将共享变量的读写放到一个 goroutine 中,其它 goroutine 通过 channel 进行读写操作,这种方式有很多好处。

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 中可以访问
    for {
        select {
        case amount := <-deposits:
            balance += amount
        case balances <- balance:
        }
    }
}

func init() {
    go teller()
}

第二种就是最常见的互斥了,共享变量要互斥访问
可以用个数为 1 的信号量(semaphore)实现互斥

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 内部提供了互斥操作

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 也需要互斥,多线程同时读取一个变量有问题吗??? Balance 也需要互斥是为了防止在写的过程中进行读取。如果在读的过程中没有线程在写多线程同时读取是没有问题的。所以为了提高读取的并发量可以用读写锁改写

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

Deposit 不变,Balance 只获取 RLock 读锁,只要没有线程在写,多个线程可同时获得 RLock 锁。

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

sync 库和 channel 的选择要看场景,哪种更简单更适合就用哪种。大部分场景可用 channel 实现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在上篇中,我们已经讨论过如何去实现一个 Map 了,并且也讨论了诸多优化点。在下篇中,我们将继续讨论如何实现一个线...
    一缕殇流化隐半边冰霜阅读 12,285评论 5 41
  • 引用自多线程编程指南应用程序里面多个线程的存在引发了多个执行线程安全访问资源的潜在问题。两个线程同时修改同一资源有...
    Mitchell阅读 6,099评论 1 7
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 9,148评论 0 11
  • Java-Review-Note——4.多线程 标签: JavaStudy PS:本来是分开三篇的,后来想想还是整...
    coder_pig阅读 5,596评论 2 17
  • 12月1日 晴 生活在这繁华城市的我们,有着自身独特的生存方式,以平和心态对待每个人,或许就有着不同的结果。
    暖心阳阅读 1,345评论 0 0