美文网首页
atomic.Value代替sync.RWMutex

atomic.Value代替sync.RWMutex

作者: laotoutou | 来源:发表于2021-01-15 22:09 被阅读0次

记一次性能优化,读公司项目代码时候,发现好些使用sync.RWMutext的使用场景:项目启动时候对高频数据缓存到内存缓存中,同时每隔一段时间重新写一下这个缓存(用一个全局变量):

type cosCred struct {
    Cred []int64
    sync.RWMutex
}

var CosCred *cosCred

// 每分钟写一次
func InitCosCred() {
    CosCred = new(cosCred)
    CosCred.Cred, _ = GetGlobalCredData()
    go func() {
        for range time.NewTicker(10 * time.Minute).C {
            cred, err := GetGlobalCredData()
            if err != nil {
                continue
            }
            CosCred.Lock()
            CosCred.Cred = cred
            CosCred.Unlock()
        }
    }()
}

// 接口会并发读
func GetCosCred() []int64 {
    CosCred.RLock()
    defer CosCred.RUnlock()
    if CosCred.Cred == nil {
        return nil
    }
    resp := CosCred.Cred
    return resp
}

看到以上场景是一个协程写,接口并发读,而写的过程是直接修改变量的值(切片引用类型,修改了全局变量指向的底层数组),只是这一个写的过程,却要在每次读的时候加读锁,其实只要换成保证原子操作的变量赋值和读取就行了,使用atomic.Value

atomic.Value封装了一个interface{}类型的v变量,简单粗暴,同时提供了Load和Store原子操作,用于给v原子赋值和读取,简单修改下:


var CosCred atomic.Value

// 每分钟写一次
func InitCosCred() {
    data := GetGlobalCredData()
    CosCred.Store(data)
    go func() {
        for range time.NewTicker(10 * time.Minute).C {
            cred, err := GetGlobalCredData()
            if err != nil {
                continue
            }
            CosCred.Store(data)
        }
    }()
}

// 接口会并发读
func GetCosCred() []int64 {
    resp, _ := CosCred.Load().([]int64)
    return resp
}

原子操作由底层硬件支持,而锁则由操作系统的调度器实现。锁应当用来保护一段逻辑,对于一个变量更新的保护,原子操作通常会更有效率

关于atomic.Value有一篇不错的blog
https://blog.betacat.io/post/golang-atomic-value-exploration/

相关文章

  • atomic.Value代替sync.RWMutex

    记一次性能优化,读公司项目代码时候,发现好些使用sync.RWMutext的使用场景:项目启动时候对高频数据缓存到...

  • value.go

    概述 atomic.Value支持不用锁的情况下并发读写"任意类型"数据 前置知识 interface底层结构 h...

  • Go - sync.RWMutex

    设计目的 大多数读请求之间互不影响,在读多写少的场景下,可以分离读写操作,提高读写并发性能. 限制 只能读读并发,...

  • Go 的 sync (同步原语)库

    官方包的注释: sync包提供基础的同步原语,sync.Mutext、sync.RWMutex、sync.Wait...

  • golang atomic.Value用法

    自定义可原子操作的变量类型 总结: atomic.Value提供了一种自定义变量类型的原子操作, 读: v.Lo...

  • golang并发编程读写锁sync.RWMutex

    一、介绍sync.RWMutex 为读写锁,lock为写锁定 ,Unlock 为写解锁,RLock为读锁,RUn...

  • Go超时锁的设计和实现

    Go提供两种锁:sync.Mutex和sync.RWMutex。 sync.Mutex: 互斥锁。任意时刻,只能有...

  • 读写锁和互斥锁 读写互斥锁,简称读写锁 mux sync.RWMutex Lock和Unlock分别对写锁进行锁定...

  • go 中的 sync.Mutex 与 sync.RWMutex

    sync.Mutex 互斥锁,不支持递归锁 sync.RWMutex 什么时候用sync.Mutex,什么时候用 ...

  • go sync包的读写锁RWMutex的使用

    sync包的读写锁RWMutex的使用(sync.RWMutex) 我们使用“读写”锁的场景主要是在多线程的安全操...

网友评论

      本文标题:atomic.Value代替sync.RWMutex

      本文链接:https://www.haomeiwen.com/subject/wtqgaktx.html