栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Golang 锁

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Golang 锁

hashmap 和 sync.Map 皆为 unscalable:并发执行 hashmap 的插入操作,因为锁的存在,使用越多cpu,平均操作耗时越长。用 sync.Map 比用 hashmap+锁 的平均操作耗时更长。

一、数据竞争

原因:多个 goroutine 同时接触一个变量,行为不可预知
认定条件:两个及以上 goroutine 同时接触一个变量,其中至少一个 goroutine 为写操作
检测方案:go run -race 或者 go test -race

二、锁的最佳实践
    减少持有时间:使用 defer 释放锁的时候注意不要增加临界区(尽量用完了就尽快解锁,而defer会在函数最后才被执行,虽然不会忘记解锁,但是加大了持有时间)优化锁的粒度:空间换时间。map 分段锁,比如一个数组长度为x,可以创建一个长度为x的 lock 数组分别对每个位置元素加锁,利用下标控制对应的锁。读写分离:尽量使用读写锁 RWMutex,不管读多写少或者读少写多的场景,相比于 sync.Mutex 仍然会有不少的性能提升;sync.Map 相比于 RWMutex 在 cpu 核数增加时性能更稳定,也是推荐使用。使用原子操作(Lock Free):使用 Go 提供的 atomic.Value。不触发调度,不阻塞执行流。相当于没有命中缓存的访存指令。atomic.Value 的前世今生
三、避免踩坑
    不要拷贝mutex(传参时要传指针,Goland 已默认提示)避免死锁,Go 的 sync.Mutex 是不可重入锁,不可以重复 lock。Go Mutex 设计思想atomic.Value 中应存入只读对象,如果需要取出来再写,则需要加上 Mutex 锁住该操作。race detector 发现潜在问题(用于单测,压测,但是会 10 倍 cpu,不要在线上环境开启)
四、锁的进化
    Mutex 设计原则:效率优先,兼顾公平正常模式:效率高,新来的goroutine直接先抢锁,无需先排队,等待超过1ms,则切换到饥饿模式 。 为什么正常模式效率高:减少调度开销,新来的不用进入队列;可以充分利用缓存饥饿模式:更公平,新来的goroutine也要先排队,完全先来后到。加锁:原子操作 -> 自旋 -> 加入队列唤醒:不是饥饿状态,可能和其他goroutine竞争;是饥饿状态,直接获得锁,更新锁的状态解锁:fast_path;slow_path
五、引用
    Go 不安全的 stringGo: 关于锁的1234Go中锁的那些姿势
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/727576.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号