当前位置: 首页 > 后端技术 > Java

为什么Go在语言层面不支持map并发?

时间:2023-04-02 00:21:02 Java

大家好,我是炸鱼。很多朋友在学习Go语言语法的时候,可能对这个问题只是看淡了。如此一来,他们一旦上手,或多或少会在一个群体中遇到好几次。甚至有一定年限的程序员也会被发现。有小伙伴疑惑,这么折腾,Go为什么不在语言层面直接支持map并发,这有什么好吃的?为什么它不被原生支持?为什么Go官方不支持它?会不会太复杂,性能太差?为什么?官方回答如下(via@gofaq):典型使用场景:map的典型使用场景是不需要多个goroutine的安全访问。非典型场景(需要原子操作):地图可能是一些更大的数据结构的一部分或已经同步的计算。性能场景考虑:如果只增加少数几个程序的安全性,导致所有map操作都处理mutex会降低大部分程序的性能。核心是:经过长时间的讨论,Go团队认为原生地图应该更适合典型的使用场景。如果是针对少数情况,会导致大部分程序付出性能代价,决定不支持原生并发map读写。并且从Go1.6开始,加入了检测机制,如果并发,就会引发异常。为什么会崩溃前面说了,从Go1.6开始,会进行nativemaps的并发检测,这对某些人来说是个“噩梦”。这里有人吐槽:“明明就是丢给我一个错误,为什么我的Go进程要直接崩溃,而且每分钟都要记一个P0”。场景枚举这里我们假设如果并发读写map是以下两种场景:Panic:程序panic->默认进入recover->不处理concurrentmap->map有脏数据->程序使用了脏数据->生成**unknown((impact.crash:程序崩溃->直接crash->保留数据(数据正常)->生成**clear((有风险。你会选择哪种解决方案?去官方有两种我选择了第二种在笔者的风险评估中,无论是编程还是生活,如何掌握随机性的确定性部分,也是一个很大的哲理,letitcrashGo官方团队选择的方法是业界经典的“letitcrash”“在许多编程语言中,行为将作为一种设计哲学来追求。letitcrash意味着工程师不必过多担心未知错误,而是进行全面的防御性编码。这种思想最经典的是erlang。小结在今天的文章中,我们介绍了为什么Go语言不支持原生map并发。核心原因是大部分场景不需要,是从性能角度考虑的。之所以直接允许map并发读写,是考虑“让它崩溃”。如果想在自己的项目中避免这种情况,可以在linter等工具链中加入racedetection(-race)来规避此类风险。您如何看待Go中的设计考虑因素?欢迎在评论区留言交流:)如有任何问题,欢迎在评论区反馈交流。最好的关系是相互成就。您的好评是炸鱼创作最大的动力。感谢您的支持。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。