Golang sync
Go1.9.2 sync库里包含下面几类:Mutex/RWMutex/Cond/WaitGroup/Once/Map/Pool
1.Mutex:互斥锁,等同于linux下的pthread_mutex_t
//多个线程同时运行,获得Mutex锁者线程优先执行,其余线程阻塞等待 func testMutex() {mutex := sync.Mutex{};for i := 0; i < 10; i++ {go func(idx int) {mutex.Lock();defer mutex.Unlock();fmt.Println("idx :=", idx);time.Sleep(time.Second);}(i)}time.Sleep(20 * time.Second);fmt.Println("Func finish."); }
2.RWMutex:读写锁,等同于linux下的pthread_rwlock_t
//写请求在读锁和写锁时都必须阻塞等待,读请求只在写锁时阻塞等待 func testRWMutex() {rwMutex := sync.RWMutex{};for i := 0; i < 10; i++ {go func(idx int) {rwMutex.RLock();defer rwMutex.RUnlock();fmt.Println("Read Mutex :",idx);}(i);go func(idx int) {rwMutex.Lock();defer rwMutex.Unlock();fmt.Println("Write Mutex :",idx);time.Sleep(time.Second);}(i);}time.Sleep(20 * time.Second);fmt.Println("Func finish."); }
3.Cond:条件变量,等同于linux下的pthread_cond_t
func testCond() {cond := sync.NewCond(&sync.Mutex{});cond.L.Lock(); //①上锁 defer cond.L.Unlock();go func() {fmt.Println("go wait lock.");cond.L.Lock(); //②等Wait解锁 defer cond.L.Unlock(); //⑤解锁后触发Waitdefer fmt.Println("go unlock.");fmt.Println("go locked.");cond.Signal(); //④触发Wait等待解锁 }()time.Sleep(time.Second);fmt.Println("start wait.");for {cond.Wait(); //③可以理解为立刻解锁并触发一个阻塞线程(如果没有阻塞线程则不触发)后立刻再上锁等待Signal信号fmt.Println("wait finish.");break;}time.Sleep(time.Second);fmt.Println("Func finish."); }
4.WaitGroup:组等待
//Add 增加等待计数;Done减少等待计数;当计数为0时触发Wait; func testWaitGroup() {waitGroup := sync.WaitGroup{};for i := 0; i < 10; i++ {waitGroup.Add(1);go func(idx int) {time.Sleep(time.Second);fmt.Println("go : ", idx);waitGroup.Done();}(i)}for{fmt.Println("start wait.");waitGroup.Wait();fmt.Println("wait finish.");break;}time.Sleep(time.Second);fmt.Println("Func finish."); }
5.Once:只执行一次
//只执行一次以后不再触发 func testOnce() {once := sync.Once{};for i := 0; i < 10; i++ {go func(idx int) {once.Do(func() {fmt.Println("Do once : ", idx); //这里只执行一次 })fmt.Println("go : ", idx);}(i)}time.Sleep(5 * time.Second);fmt.Println("Func finish."); }
6.Map:线程安全map
func testMap() {syncMap := sync.Map{};for i := 0; i < 10; i++ {go func(idx int) {//如果没有则保存起来_, ok := syncMap.LoadOrStore(idx, " StrVal = "+strconv.FormatInt(int64(idx), 10));if !ok {fmt.Println("Store idx = ",idx);}}(i)go func(idx int) {val, ok := syncMap.Load(idx);if ok {fmt.Println("Load success idx = ", idx, val);} else {fmt.Println("Load fail idx = ", idx)}}(i)}time.Sleep(5 * time.Second);fmt.Println("Func finish."); }
7.Pool:线程安全对象池
func testPool() {p := &sync.Pool{New: func() interface{} {return -1;},}for i := 0; i < 10; i++ {go func(idx int) {p.Put(idx);}(i)}//取出来的对象是无序的for i := 0; i < 20; i++ {go func() {val := p.Get();fmt.Println("Get val = ", val);}()}time.Sleep(5 * time.Second);fmt.Println("Func finish."); }
使用Pool一定要注意一下问题:
1.用途仅仅是增加对象重用的几率,减少gc的负担,而开销方面也不是很便宜的。
2.GC会将Pool清理掉。
3.Get不能保证将Put进去的全部取出来!如下例子:
func testPoolPutGet(){myPool := &sync.Pool{New: func() interface{} {return 0;},}myPool.Put(1) //放入1myPool.Put(2) //放入2 time.Sleep(time.Second)p1 := myPool.Get().(int)fmt.Println(p1) // 获得2 p2 := myPool.Get().(int)fmt.Println(p2) // 获得0,而不是1! }
4.关于Pool的实现原理,可以参考《go语言的官方包sync.Pool的实现原理和适用场景》
以上。
转载于:https://www.cnblogs.com/chevin/p/8083022.html
Golang sync相关推荐
- Golang sync.Map 原理(两个map实现 读写分离、适用读多写少场景)
参考: 由浅入深聊聊Golang的sync.Map 通过对源码的逐行分析,清晰易懂 Golang sync.Map原理 通过向 sync.Map 中增删改查来介绍sync.Map的底层原理 Golan ...
- Golang sync.Mutex源码分析
sync.Mutex是一个不可重入的排他锁. 这点和Java不同,golang里面的排它锁是不可重入的.当一个 goroutine 获得了这个锁的拥有权后, 其它请求锁的 goroutine 就会阻塞 ...
- golang sync.Map 使用
自1.9版本以后提供了sync.Map,支持多线程并发读写,比之前的加锁map性能要好一点. 提供一下几个方法: type Map//删除指定keyfunc (m *Map) Delete(key i ...
- [转载]golang sync.Pool
2019独角兽企业重金招聘Python工程师标准>>> Go 1.3 的sync包中加入一个新特性:Pool. 官方文档可以看这里http://golang.org/pkg/sync ...
- Golang sync.pool对象池
概览 Goalng中通过sync.pool提供了对象池的实现来达到对象复用的目的.在netty中,也通过Recycle类实现了类似的对象池实现.在netty的对象池Recycle中,当A线程需要将B线 ...
- golang sync.map
在golang中,线程安全的map实现为sync.Map,相较于java中线程安全的map ConcurrentHashMap,在设计与实现上都有巨大的差别. java中的ConcurrentHash ...
- Golang sync.Pool 简介与用法
文章目录 1.简介 2.应用 2.1 标准库的应用 2.2 复用 bytes.Buffer 参考文章 1.简介 Pool 是可伸缩.并发安全的临时对象池,用来存放已经分配但暂时不用的临时对象,通过对象 ...
- Golang sync.WaitGroup 简介与用法
1.简介 sync.WaitGroup 用于阻塞等待一组 Go 程的结束.主 Go 程调用 Add() 来设置等待的 Go 程数,然后该组中的每个 Go 程都需要在运行结束时调用 Done(), 递减 ...
- Golang sync.Map 简介与用法
Golang 中的 map 在并发情况下,只读是线程安全的,并发读写线程不安全.为了解决这个问题,Golang 提供了语言层级的并发读写安全的 sync.Map. type Map struct {/ ...
- Golang sync.Mutex 与 sync.RWMutex
文章目录 1.sync.Mutex 2.sync.RWMutex 2.1 Lock()与Unlock() 2.2 RLock() 和 RUnlock() 2.3 错误使用异常 参考文献 Golang ...
最新文章
- Linux iscsi磁盘共享挂载
- FM之DATE_CHECK_PLAUSIBILITY
- Java集合篇:Map总结
- 自已做的第一个autoconf程序(不断完善中)
- spring(6) 渲染web视图
- Linux学习笔记006-启动流程
- jq之slideDown() stop()
- 庆祝一下博文过100篇访问量过30万
- 【资源】About Face4交互设计精髓,英文原版,彩色pdf下载
- Python版解决中文字符串错误
- 找到某个关键字 同义词词林 python_3.6 什么是LSI关键字?为什么它对SEO很重要?...
- 小王子星球调色Web版 - the little prince
- 西安大略大学计算机专业排名,加拿大大学计算机专业排名一览
- android表情功能开发
- 【JAVASE】多线程编程基础
- pandas已知数值怎么找位置_pandas.dataframe中根据条件获取元素所在的位置方法(索引)...
- 10月18日~23日 产品
- python从TXT文件读取数据并处理
- 直播软件app开发:如何开发一个可以免费打扑克的直播应用?
- CentOS8 Nomad安装(2)
热门文章
- c++ege为什么直线画不出来_今天让我们来练习画一款椭圆茶几
- unity获取电磁笔压感_1024级压感 原道W8S电磁笔的秘密
- VR原理讲解及开发入门
- 服务器上安装n点虚拟主机,N点虚拟主机管理系统之①-运行N点
- ios 裁剪框大小_iOS实现裁剪框和图片剪裁功能
- 2021未来科学大奖揭晓:SARS病原发现者、上海交大张杰教授等4人获得百万奖金...
- 日本人真会玩!3天众筹60万元来造“机器猫”,会说话摇尾巴的那种
- 潘建伟团队最新研究成果登上Nature:首次实现1120公里长距离无中继纠缠量子密钥分发...
- 一文看懂地平线如何再造摩尔定律| 地平线大牛讲堂
- 禾多推出高精度定位和自动驾驶验证平台!倪凯:助力行业量产,定位中国向导...