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相关推荐

  1. Golang sync.Map 原理(两个map实现 读写分离、适用读多写少场景)

    参考: 由浅入深聊聊Golang的sync.Map 通过对源码的逐行分析,清晰易懂 Golang sync.Map原理 通过向 sync.Map 中增删改查来介绍sync.Map的底层原理 Golan ...

  2. Golang sync.Mutex源码分析

    sync.Mutex是一个不可重入的排他锁. 这点和Java不同,golang里面的排它锁是不可重入的.当一个 goroutine 获得了这个锁的拥有权后, 其它请求锁的 goroutine 就会阻塞 ...

  3. golang sync.Map 使用

    自1.9版本以后提供了sync.Map,支持多线程并发读写,比之前的加锁map性能要好一点. 提供一下几个方法: type Map//删除指定keyfunc (m *Map) Delete(key i ...

  4. [转载]golang sync.Pool

    2019独角兽企业重金招聘Python工程师标准>>> Go 1.3 的sync包中加入一个新特性:Pool. 官方文档可以看这里http://golang.org/pkg/sync ...

  5. Golang sync.pool对象池

    概览 Goalng中通过sync.pool提供了对象池的实现来达到对象复用的目的.在netty中,也通过Recycle类实现了类似的对象池实现.在netty的对象池Recycle中,当A线程需要将B线 ...

  6. golang sync.map

    在golang中,线程安全的map实现为sync.Map,相较于java中线程安全的map ConcurrentHashMap,在设计与实现上都有巨大的差别. java中的ConcurrentHash ...

  7. Golang sync.Pool 简介与用法

    文章目录 1.简介 2.应用 2.1 标准库的应用 2.2 复用 bytes.Buffer 参考文章 1.简介 Pool 是可伸缩.并发安全的临时对象池,用来存放已经分配但暂时不用的临时对象,通过对象 ...

  8. Golang sync.WaitGroup 简介与用法

    1.简介 sync.WaitGroup 用于阻塞等待一组 Go 程的结束.主 Go 程调用 Add() 来设置等待的 Go 程数,然后该组中的每个 Go 程都需要在运行结束时调用 Done(), 递减 ...

  9. Golang sync.Map 简介与用法

    Golang 中的 map 在并发情况下,只读是线程安全的,并发读写线程不安全.为了解决这个问题,Golang 提供了语言层级的并发读写安全的 sync.Map. type Map struct {/ ...

  10. Golang sync.Mutex 与 sync.RWMutex

    文章目录 1.sync.Mutex 2.sync.RWMutex 2.1 Lock()与Unlock() 2.2 RLock() 和 RUnlock() 2.3 错误使用异常 参考文献 Golang ...

最新文章

  1. Linux iscsi磁盘共享挂载
  2. FM之DATE_CHECK_PLAUSIBILITY
  3. Java集合篇:Map总结
  4. 自已做的第一个autoconf程序(不断完善中)
  5. spring(6) 渲染web视图
  6. Linux学习笔记006-启动流程
  7. jq之slideDown() stop()
  8. 庆祝一下博文过100篇访问量过30万
  9. 【资源】About Face4交互设计精髓,英文原版,彩色pdf下载
  10. Python版解决中文字符串错误
  11. 找到某个关键字 同义词词林 python_3.6 什么是LSI关键字?为什么它对SEO很重要?...
  12. 小王子星球调色Web版 - the little prince
  13. 西安大略大学计算机专业排名,加拿大大学计算机专业排名一览
  14. android表情功能开发
  15. 【JAVASE】多线程编程基础
  16. pandas已知数值怎么找位置_pandas.dataframe中根据条件获取元素所在的位置方法(索引)...
  17. 10月18日~23日 产品
  18. python从TXT文件读取数据并处理
  19. 直播软件app开发:如何开发一个可以免费打扑克的直播应用?
  20. CentOS8 Nomad安装(2)

热门文章

  1. c++ege为什么直线画不出来_今天让我们来练习画一款椭圆茶几
  2. unity获取电磁笔压感_1024级压感 原道W8S电磁笔的秘密
  3. VR原理讲解及开发入门
  4. 服务器上安装n点虚拟主机,N点虚拟主机管理系统之①-运行N点
  5. ios 裁剪框大小_iOS实现裁剪框和图片剪裁功能
  6. 2021未来科学大奖揭晓:SARS病原发现者、上海交大张杰教授等4人获得百万奖金...
  7. 日本人真会玩!3天众筹60万元来造“机器猫”,会说话摇尾巴的那种
  8. 潘建伟团队最新研究成果登上Nature:首次实现1120公里长距离无中继纠缠量子密钥分发...
  9. 一文看懂地平线如何再造摩尔定律| 地平线大牛讲堂
  10. 禾多推出高精度定位和自动驾驶验证平台!倪凯:助力行业量产,定位中国向导...