博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go并发编程之美-条件变量
阅读量:6328 次
发布时间:2019-06-22

本文共 1693 字,大约阅读时间需要 5 分钟。

一、前言

go语言类似Java JUC包也提供了一些列用于多线程之间进行同步的措施,比如低级的同步措施有 锁、CAS、原子变量操作类。相比Java来说go提供了独特的基于通道的同步措施。本节我们先来看看go中与锁相关的条件变量

二、条件变量

在java中条件变量是与具体的锁想关联的,在go中也是这样的。

package mainimport (    "fmt"    "sync"    "time")var (    counter int                   //计数器    wg      sync.WaitGroup        //信号量    lock    sync.Mutex            //互斥锁    cond    = sync.NewCond(&lock) //条件变量)func main() {    //1.获取锁    cond.L.Lock()    fmt.Println("main  thread got lock  ")    //2.开启线程执行一些事情    go doSomething()    //3.用与锁关联的条件变量的wait方法    fmt.Println("main thread begin wait  ")    cond.Wait()    fmt.Println("main thread end wait  ")    //4.释放锁    cond.L.Unlock()    fmt.Println("main thread release lock  ")}func doSomething() {    //2.1激活阻塞到条件变量的wait方法的一个线程    time.Sleep(time.Second * 2)    //2.2获取锁    fmt.Println("sub thread begin get lock ")    //cond.L.Lock()    fmt.Println("sub thread  got lock ")    time.Sleep(5 * time.Second)    cond.Signal()    //2.3释放锁    //cond.L.Unlock()    fmt.Println("sub thread release lock ")}
  • go中使用sync.NewCond(&lock)创建一个条件变量,其中lock可以是互斥锁或者读写锁
  • 主线程线程先获取了lock锁(cond.L就是lock变量),然后开启了子线程,然后调用了条件变量的wait方法,main线程然后被阻塞,并且main线程会释放获取的lock锁。
  • 子线程则首先尝试获取lock锁,如果是在main线程执行条件变量的wait前尝试获取锁,则子线程会被阻塞,等main线程执行到wait后,main函数释放锁后,子线程会获取锁成功。
  • 子线程获取锁成功后,会先休眠5s然后释放锁,然后调用条件变量的signal方法,这时候main线程则会重新获取到锁,然后从wait返回。

需要注意的是调用条件变量的signal方法的线程在调用该方法前,获取关联的lock锁这个并不是必须的,读者可以注释获取和释放锁代码,也是OK的。

与Java中类似调用条件变量的signal会激活一个线程,调用Broadcast会激活所有阻塞到条件变量wait方法的线程。

另外需要注意,一般调用线程应该使用循环检查方式调用条件变量的wait方法,以避免虚假唤醒等问题。

三、总结

go中条件变量与Java中条件变量类似,但是也有不同,相同在于条件变量都是与锁关联的,并且只有当线程获取到锁后才可以调用其关联的条件变量的wait方法,否则会抛出异常,另外当线程阻塞到wait方法后,当前线程会释放已经获取的锁。不同在于Java中只有当线程获取到锁后才可以调用其关联的条件变量的signal方法,否则会抛出异常,但是在go中调用线程调用signal前获取锁不是必须的。

转载地址:http://dpwoa.baihongyu.com/

你可能感兴趣的文章
Android之读取 AndroidManifest.xml 中的数据:版本号、应用名称、自定义K-V数据(meta-data)...
查看>>
R学习笔记 第五篇:字符串操作
查看>>
在Mac OS下配置PHP开发环境
查看>>
(转)介绍下Nuget在传统Asp.net项目中的使用
查看>>
C# ArcEngine 实现点击要素高亮并弹出其属性
查看>>
初识GO语言——安装Go语言
查看>>
SDK命令行操作
查看>>
基于Bootstrap的DropDownList的JQuery组件的完善版
查看>>
EXTJS学习系列提高篇:第二十四篇(转载)作者殷良胜,ext2.2打造全新功能grid系列--阅增删改篇...
查看>>
Hadoop MapReduce编程 API入门系列之分区和合并(十四)
查看>>
判断二叉树是否平衡、是否完全二叉树、是否二叉排序树
查看>>
并查集的应用之求解无向图中的连接分量个数
查看>>
7个神奇的jQuery 3D插件
查看>>
在线浏览PDF之PDF.JS (附demo)
查看>>
波形捕捉:(3)"捕捉设备"性能
查看>>
AliOS Things lorawanapp应用介绍
查看>>
美国人的网站推广方式千奇百怪
查看>>
java web学习-1
查看>>
用maven+springMVC创建一个项目
查看>>
linux设备驱动第四篇:以oops信息定位代码行为例谈驱动调试方法
查看>>