使用Go1.9的sync.map

Go1.9引入了并发安全的sync.Map,对比之前的自封装加锁map,它提供了Store、Load、Delete和Range等方法。本文详细介绍了这四个方法的用法,并探讨了sync.Map在性能上的提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Go1.9之前,go自带的map不是并发安全的,也就是说,我们需要自己再封装一层,给map加上把读写锁,比如像下面这样:

type MapWithLock struct {
    sync.RWMutex
    M map[string]Kline
}

用MapWithLock的读写锁去控制map的并发安全。
但是到了Go1.9发布,它有了一个新的特性,那就是sync.map,它是原生支持并发安全的map,不过它的用法和以前我们熟悉的map完全不一样,主要还是因为sync.map封装了更为复杂的数据结构,以实现比之前加锁map更优秀的性能。

使用

var mySMap sync.Map

先声明

Store方法

mySMap.Store(exchangeEntity.Exchange, exchangeEntity.ExchangeCnName)  //业务逻辑,其实两个都是string类型

这个相当于是写map,第一个参数是key,第二个参数是value

Load方法

func GetMySMapValue(tradingPlace string) string {
    value, ok := mySMap.Load(tradingPlace)
    if ok {
        mySMapValue, valid := value.(string)
        if valid {
            return mySMapValue
        } else {
            logger.Debug("invalid type assertion error", value)
            return ""
        }
    }
    return ""
}

这里我对Load进行了一层封装,因为Load方法返回的是interface{}和bool,所以需要先判断是否存在这个key-value,然后再进行类型断言,所以封装起来对外部调用会更友好。

Delete方法

mySMap.Delete(exchangeEntity.Exchange)

删除比较简单,直接传进去想删除的key就可以了

Range方法

    mySMap.Range(func(key, value interface{}) bool {
        tmpval, valid := value.(string)
        if !valid {
            logger.Debug("invalid type assertion error", value)
            return true   //返回true,则range下一个key
        }
        if tmpval.HotFlag == true {  //业务逻辑,不用管
            tmpkey, valid := key.(string)
            if !valid {
                logger.Debug("invalid type assertion error", key)
                return true  //返回true,则range下一个key
            }
            result = append(result, tmpkey)  //业务逻辑,不用管
        }
        return true
    })

注意sync.Map的Range依旧是无序的,我们需要传给Range方法一个函数对象,这个闭包函数接受key和value,返回bool,返回true则直接进行下一个循环,类似continue。返回false则直接终止Range,类似break。

sync.Map性能

Go 1.9源代码中提供了性能的测试: map_bench_test.go、map_reference_test.go
相比较以前的解决方案,性能多少回有些提升,在性能瓶颈的地方,可以考虑使用sync.Map来代替原来方案。

BenchmarkHitAll/*sync.RWMutexMap-4       20000000            83.8 ns/op
BenchmarkHitAll/*sync.Map-4              30000000            59.9 ns/op
BenchmarkHitAll_WithoutPrompting/*sync.RWMutexMap-4             20000000            96.9 ns/op
BenchmarkHitAll_WithoutPrompting/*sync.Map-4                    20000000            64.1 ns/op
BenchmarkHitNone/*sync.RWMutexMap-4                             20000000            79.1 ns/op
BenchmarkHitNone/*sync.Map-4                                    30000000            43.3 ns/op
BenchmarkHit_WithoutPrompting/*sync.RWMutexMap-4                20000000            81.5 ns/op
BenchmarkHit_WithoutPrompting/*sync.Map-4                       30000000            44.0 ns/op
BenchmarkUpdate/*sync.RWMutexMap-4                               5000000           328 ns/op
BenchmarkUpdate/*sync.Map-4                                     10000000           146 ns/op
BenchmarkUpdate_WithoutPrompting/*sync.RWMutexMap-4              5000000           336 ns/op
BenchmarkUpdate_WithoutPrompting/*sync.Map-4                     5000000           324 ns/op
BenchmarkDelete/*sync.RWMutexMap-4                              10000000           155 ns/op
BenchmarkDelete/*sync.Map-4                                     30000000            55.0 ns/op
BenchmarkDelete_WithoutPrompting/*sync.RWMutexMap-4             10000000           173 ns/op
BenchmarkDelete_WithoutPrompting/*sync.Map-4                    10000000           147 ns/op
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值