美文网首页
golang并发编程tips

golang并发编程tips

作者: 江江的大猪 | 来源:发表于2020-01-27 18:50 被阅读0次

作为服务端的开发,最关注的就是并发编程,每个从java接触到golang的小伙伴应该都会有一些共同的困惑,做个总结

  • 从java转到golang的一些类比:

    • atomic.Value的用途和volatile类似
    • sync.Mutex、sync.RWMutex和ReentrantLock、ReentrantReadWriteLock类似
    • sync.WaitGroup和CountDownLauch类似
    • channel和future或者阻塞队列类似
    • sync.Map和ConcurrentHashMap类似
    • atomic包对应java的原子类
    • select特性没想到在java中有对应的东西,select加channel使用很广,配合default可以实现不阻塞,有很多妙用
    • sync.Once可以很方便的实现单例模式,效果相当于java中的双重synchronized的懒加载
  • 在官方文档golang的内存模型描述中没有对可见性有明确的说明,官方文档对保证并发安全的说明就一句话:use explicit synchronization

  • golang中经常会看到结构体的属性中有sync.mutex,就是同步处理结构体对象用的

  • golang中没有类似java的volatile关键字,但是有atomic.Value可以保证读写的原子性。

    • 举个例子:假设我们有一个结构体存储着应用运行中的各种配置,有一个协程专门负责更新Config,用一个新的DynamicConfig对象赋值给Config(copy on write),其他的协程从Config中读取配置。如果我们不做同步处理的话,很有可能Config中的数据有的是新的有的是老的
    • 聪明的小伙伴为了避免上面那种情况可能会考虑使用结构体的指针作为全局变量ConfigPtr进行操作,因为指针的读写按照道理应该是原子操作。有大神看了编译后的汇编发现确实是原子操作就这么用了,但是这样其实是依赖的golang编译机制,golang从语言层面并不提供原子保证。加入-race参数的话会看到data race警告。但是有很多开源项目都有在并发情况下用一个新map去替换老map的操作,使用起来也没啥问题,就是会有race警告,这就很尴尬了。。。
    • 最好的做法应该是ConfigAtom这样使用atomic.Value,很多开源库里都有这种做法,其实使用读写锁也可以,就是性能差了点
type DynamicConfig struct {
    MysqlUrl          string
    MysqlMaxIdleConns int
    MysqlMaxOpenConns int
    MysqlMaxLifetime  int
}

var Config DynamicConfig
var ConfigPtr *DynamicConfig
var ConfigAtom atomic.Value
  • golang中的channel粗略的可以看做java中的future或者阻塞队列,虽然golang中老生常谈的就是要用通信来共享内存,不要通过共享内存来通信,这句话的意思被很多人曲解成了在golang中保证并发安全最好都用channel。但其实这句话的意思是如果多个协程间有数据传递交互的话确实是用channel更好,但是就像上面那样的全局配置对象,肯定是使用共享内存更加合适。
  • golang中atomic包中的原子操作只有整数类型,其他的类型如果要原子的load、store、cas操作需要转换成*unsafe.Pointer,但是golang的unsafe包和java的unsafe包一样是不推荐使用的,后续版本可能会有变化或者移除,但是现在已经有很多地方都在使用unsafe了,所以我猜测后续golang应该不会对这块有什么变化,或者是提供类似python2迁移python3的工具
  • golang为了提醒大家map不是并发安全的,当并发写入同一个map时会panic而且不会被recover到!!!使用sync.Map保证并发安全
  • channel的性能比sync.mutex低,这点有点违反使用者的第一感觉

相关文章

  • golang并发编程tips

    作为服务端的开发,最关注的就是并发编程,每个从java接触到golang的小伙伴应该都会有一些共同的困惑,做个总结...

  • Golang聚合

    教程 Go Web 编程Go语言圣经(中文版) Tips Golang 学习笔记——交叉编译 & 部署Golang...

  • Golang的并发编程

    golang是为并发而生的语言。优雅的并发编程范式,完善的并发支持,出色的并发性能是golang区别于其他语言的一...

  • Golang的并发编程

    Golang中的并发编程 Golang语言中,并发使用的协程的机制,实现起来也是十分的方便,使用go关键字即可。 ...

  • Golang并发编程

    Go 语言简介(下)— 特性 并发不是并行Go负载均衡 一个Go例程(Goroutines)就是一个和其它Go例程...

  • Golang并发编程

    在Go语言中,语言本身就已经实现和支持了并发, 我们只需要通过go关键字来开启goroutine即可。 gouro...

  • golang并发编程

    https://go101.org/article/channel-use-cases.html https://...

  • 【转载】Golang处理大数据时使用高效的Pipeline(流水

    并发是件技术活 Golang被证明非常适合并发编程,goroutine比异步编程更易读、优雅、高效。本文提出一个适...

  • java并发编程tips

    一:synchronized synchronized中文解释是同步,那么什么是同步呢,解释就是程序中用于控制不同...

  • Go goroutine

    Golang特色之一是支持高并发编程模型,以Goroutine作为基本的并发执行单元。 Goroutine是轻量级...

网友评论

      本文标题:golang并发编程tips

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