zoukankan      html  css  js  c++  java
  • atomic.Value代替sync.RWMutex

    记一次性能优化,读公司项目代码时候,发现好些使用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/



    作者:laotoutou
    链接:https://www.jianshu.com/p/8b3487537001
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    react按钮防抖
    mac解决 gyp: No Xcode or CLT version detected!
    offsetTop、getBoundingClientRect().top
    纯前端实现微信自定义分享
    redux概念
    数字验证码多个输入框实现一个输入框效果
    使用vue-cli脚手架工具搭建vue工程项目以及配置路由
    jq实现广告栏单行或者多行上下无缝接滚动
    ant pagination分页
    小程序广告位上下滚动的效果
  • 原文地址:https://www.cnblogs.com/ExMan/p/14536824.html
Copyright © 2011-2022 走看看