有时候在Go语言代码中可能会存在多个goroutine同时操作一个资源的情况,这种时候就会发生竞态问题(数据竞态),go语言可以使用互斥锁来解决这个问题,互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源,可以使用sync包的Mutex类型来实现互斥锁,其他的goroutine则在等待锁,当互斥锁释放后,等待的goroutine才可以获取锁进入临界区,多个goroutine同时等待一个锁时,唤醒的策略是随机的,下面是一个例子,如果没有加锁那么最终的结果是错误的,其实就是线程安全问题,多个线程同时对全局变量进行修改这样就会影响另外的线程:

package mainimport ("fmt""sync"
)var x int64
var wg sync.WaitGroup
var lock sync.Mutexfunc add() {for i := 0; i < 5000000; i++ {lock.Lock() // 加锁x = x + 1lock.Unlock() // 解锁}wg.Done()
}func main() {wg.Add(2)go add()go add()wg.Wait()fmt.Println(x)
}

读写互斥锁

互斥锁是完全互斥的,但是有很多时候是读多写少的,当我们并发的去读取一个资源不涉及资源修改的时候没有必要加锁,所以这种情况下使用读写锁是更好的一种选择,在Go语言中可以使用sync包中的RWMutex类型,读写锁分为两种:读锁和写锁。当一个goroutine获取读锁之后,其他的goroutine如果是获取读锁会继续获得锁,如果是获取写锁就会等待,当一个goroutine获取写锁之后,其他的goroutine无论是获取读锁还是写锁都会等待,下面是一个例子:

package mainimport ("fmt""sync""time"
)var (x      int64wg     sync.WaitGrouprwlock sync.RWMutex
)func write() {rwlock.Lock() // 加写锁x = x + 1time.Sleep(10 * time.Millisecond) // 假设读操作耗时10毫秒rwlock.Unlock()                   // 解写锁wg.Done()
}func read() {rwlock.RLock()               // 加读锁time.Sleep(time.Millisecond) // 假设读操作耗时1毫秒rwlock.RUnlock()             // 解读锁wg.Done()
}func main() {start := time.Now()// 使用go关键字启动10个写的协程for i := 0; i < 10; i++ {wg.Add(1)// 启动一个协程go write()}// 使用go关键字启动1000个读的协程for i := 0; i < 1000; i++ {wg.Add(1)go read()}wg.Wait()end := time.Now()fmt.Println(end.Sub(start))
}

Go语言并发安全与锁相关推荐

  1. golang语言并发与并行——goroutine和channel的详细理解

    转载自: http://blog.csdn.net/skh2015java/article/details/60330785 http://blog.csdn.net/skh2015java/arti ...

  2. 《Concurrency in Go》阅读笔记 -- 第三章:Go语言并发组件

    <Concurrency in Go> 本章节从goroutine入手,讲解go语言的各种并发原语.在讲解完goroutine之后,对于传统的内存同步访问的并发原语:sync包中的Mute ...

  3. go语言怎么 控制一个变量输入的范围_go语言并发原理和机制【二】

    上图同样来自bing每日壁纸.很应景~~ 老规矩吧,废话也懒得说了.接上一篇: 甘蔗:go语言并发原理和机制[一]​zhuanlan.zhihu.com 目录 1.再探协程 什么是协程序,上一篇文章仅 ...

  4. 第09章 Go语言并发,Golang并发

    并发指在同一时间内可以执行多个任务.并发编程含义比较广泛,包含多线程编程.多进程编程及分布式程序等.本章讲解的并发含义属于多线程编程. Go 语言通过编译器运行时(runtime),从语言上支持了并发 ...

  5. 融云开发漫谈:你是否了解Go语言并发编程的第一要义?

    2007年诞生的Go语言,凭借其近C的执行性能和近解析型语言的开发效率,以及近乎完美的编译速度,席卷全球.Go语言相关书籍也如雨后春笋般涌现,前不久,一本名为<Go语言并发之道>的书籍被翻 ...

  6. java并发框架支持锁包括,tip/面试题_并发与多线程.md at master · 171437912/tip · GitHub...

    01. java用()机制实现了进程之间的同步执行 A. 监视器 B. 虚拟机 C. 多个CPU D. 异步调用 正解: A 解析: 监视器机制即锁机制 02. 线程安全的map在JDK 1.5及其更 ...

  7. 学习笔记(19):Python网络编程并发编程-互斥锁

    立即学习:https://edu.csdn.net/course/play/24458/296430?utm_source=blogtoedu 1.互斥锁: 多进程间的内存是相互隔离的,因此其数据也是 ...

  8. java并发框架支持锁包括,jdk1.8锁

    JDK1.8有什么锁?_李广进的博客-CSDN博客 2020年4月23日 18.排他锁(不包含),X锁,若事务T对数据对象A加上x锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直 ...

  9. 并发加对象锁_通用并发对象池

    并发加对象锁 在本文中,我们将介绍如何在Java中创建对象池. 近年来,JVM的性能成倍增加,大多数类型的对象几乎都变得多余,从而提高了对象池的性能. 从本质上讲,对象的创建不再像以前那样昂贵. 但是 ...

最新文章

  1. 阿里云服务器ECS Linux系统分析nginx或apache当天访问最多的IP
  2. 前台提示_住哲随手记:前台工作备忘录,记你想记的所有事
  3. 剑指offer三:从尾到头打印链表
  4. linux udp套接字编程获取报文源地址和源端口(二)
  5. 如何把class里的vector结构体memcpy出来_面试官:请说出线程安全的 ArrayList 有哪些,除了Vector...
  6. c++ char*初始化_C开发实战-深入理解指针
  7. 改动Xmodem/Zmodem上传下载路径
  8. Ubuntu18系统安装使用Nginx
  9. 漫谈数据仓库之拉链表(原理、设计以及在Hive中的实现)
  10. 即时通讯视频聊天原理是什么
  11. MV178——我的心灵家园
  12. Origin2018安装与使用(整理中)
  13. 前端大神司徒正美突发病逝,再度思考健康与金钱
  14. jmeter--解决登录接口只执行一次和多接口依赖的问题(使用事务控制器和循环控制器)
  15. 网络用语html,最新网络用语
  16. 中考落幕|教育部:力争到2022年全面实行美育中考,美育到底考什么?
  17. 萤石云枪机球机云台接入控制实战-含源码-layui
  18. 音频设置 audio
  19. android 阿拉伯语文字方向,android – 如何将RTL文本(阿拉伯语)绘制到位图并正确排序?...
  20. 券商如何做好机构服务

热门文章

  1. QQ邮箱一直显示正在发送或右侧联系人一直在装载
  2. AE制作文字模糊特效
  3. 坑爹的MediaPlayer.isPlaying()
  4. [渝粤教育] 南京大学 建筑设备 参考 资料
  5. iOS 10.2 越狱更新到yalu102 beta7,很稳定,很多注意事项及修复ssh和scp连接教程
  6. consume(consume名词)
  7. android车载应用市场,车载市场
  8. arm linux源更新,[Linux] - Manjaro ARM 系统配置(更新镜像源,安装 Docker 和 Dotnet Core)...
  9. 电脑摄像头一会好使一会不好使
  10. MYSQL系列---默认隔离级别所引发的问题