有缓冲的通道相比于无缓冲通道,多了一个缓存的功能,如下图描述的一样:

从图上可以明显看到和无缓冲通道的区别,无缓冲必须两个Goroutine都进入通道才能进行数据的交换,这个不用,如果数据有,直接就能拿走。

package ChannelDemo

import (
"fmt"
"math/rand"
"sync"
"time"
) const (
numberGoroutines =
taskLoad =
) var bufferWg sync.WaitGroup func init() {
rand.Seed(time.Now().Unix())
} func main() {
//创建了一个10任务的缓冲通道
tasks := make(chan string, taskLoad)
bufferWg.Add(numberGoroutines) //创建4个Goroutine
for gr := ; gr <= numberGoroutines; gr++ {
go worker(tasks, gr)
} //向缓冲通道中放入数据
for post := ; post <= taskLoad; post++ {
tasks <- fmt.Sprintf("Task : %d", post)
} close(tasks) bufferWg.Wait()
} func worker(tasks chan string, worker int) {
defer bufferWg.Done() for {
task, ok := <-tasks
if !ok {
fmt.Printf("Worker: %d : 结束工作 \n", worker)
return
} fmt.Printf("Worker: %d : 开始工作 %s\n", worker, task) //随机处理一下工作的时间
sleep := rand.Int63n()
time.Sleep(time.Duration(sleep) * time.Millisecond) fmt.Printf("Worker: %d : 完成工作 %s\n", worker, task)
}
}

运行结果:

Worker:  : 开始工作 Task :
Worker: : 开始工作 Task :
Worker: : 开始工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 结束工作
Worker: : 完成工作 Task :
Worker: : 结束工作
Worker: : 完成工作 Task :
Worker: : 结束工作
Worker: : 完成工作 Task :
Worker: : 结束工作

因为哪一个worker先从通道中取值有系统自己进行调度的,所以每次运行的结果稍微不同,但是相同的是10个任务被4个协程有条不紊的完成了

注意:main中有一句代码 Close(tasks) 关闭通道的代码非常重要。当通道关闭后,goroutine 依旧可以从通道接收数据,但是不能再向通道里发送数据。

能够从已经关闭的通道接收数据这一点非常重要,因为这允许通道关闭后依旧能取出其中缓冲的全部值,而不会有数据丢失.

五、总结

无缓冲的通道保证同时交换数据,而有缓冲的通道不做这种保证。

Go语言的通道(2)-缓冲通道的更多相关文章

  1. Go语言的通道(1)-无缓冲通道

    前言: 上文中我们采用了[原子函数]已经[共享锁]两种方式分别对多个goroutine进行了同步,但是在go语言中提供了另一种更好的方式,那就是使用通道(Channel). 一.通道是什么? 其实无论 ...

  2. golang channel无缓冲通道会发生阻塞的验证

    公司搞了午间技术par,本周我讲的主题是关于无缓冲通道channel是否会发生阻塞,并进行了验证. go语言中channel分为无缓冲通道和有缓冲通道两种 channel提供了一种在goroutine ...

  3. [Go] golang无缓冲通道实现工作池控制并发

    展示如何使用无缓冲的通道创建一个goroutine池,控制并发频率1.无缓冲通道保证了两个goroutine之间的数据交换2.当所有的goroutine都忙的时候,能够及时通过通道告知调用者3.无缓冲 ...

  4. [Go] golang缓冲通道实现资源池

    go的pool资源池:1.当有多个并发请求的时候,比如需要查询数据库2.先创建一个2个容量的数据库连接资源池3.当一个请求过来的时候,去资源池里请求连接资源,肯定是空的就创建一个连接,执行查询,结束后 ...

  5. [Go] golang缓冲通道实现管理一组goroutine工作

    通道1.当一个资源需要在goroutine之间共享时,通道在goroutine之间架起了一个管道2.无缓冲通道和有缓冲通道,make的第二个参数就是缓冲区大小3.无缓冲通道需要发送和接收都准备好,否则 ...

  6. Golang并发编程有缓冲通道和无缓冲通道(channel)

    无缓冲通道 是指在接收前没有能力保存任何值得通道.这种类型的通道要求发送goroutine和接收goroutine同时准备好,才能完成发送和接收操作.如果两个goroutine没有同时准备好,通道会导 ...

  7. [GO]有缓冲通道

    有缓冲通道就是在有能力保留数据的通道,那么通道在满的时候或者通道是空的时候,存数据和取数据就会发生阻塞 package main import ( "fmt" "time ...

  8. [GO]无缓冲通道(unbuffered channel)

    无缓冲通道(unbuffered channel)是指在接收前没有能力保存任何值的通道,在之前的例子中使用的都是无缓冲通道,需要注意的是,对于无缓冲通道而言,不管是往通道里写数据还是从通道里读数据,都 ...

  9. [Golang]-5 协程、通道及其缓冲、同步、方向和选择器

    目录 协程 通道 通道缓冲 通道同步 通道方向 通道选择器 协程 Go 协程 在执行上来说是轻量级的线程. 代码演示 import ( "fmt" "time" ...

随机推荐

  1. 解决Centos7 yum 出现could not retrieve mirrorlist 错误

    刚通过VMware12安装了centos7.x后,使用ip addr查看centos局域网的ip发现没有,使用yum安装一些工具包时也出现报错: Loaded plugins: fastestmirr ...

  2. ArcGIS Server注册数据库——以oracle为例

    原创文章,转载须标明出处自: https://www.cnblogs.com/gisspace/p/9089117.html ------------------------------------- ...

  3. Android网页打开指定App

    一.只打开APP操作 通过用手机的浏览器(内置,第三方都可)访问一个网页,实现点击一个链接启动自己的应用,并传递数据. 首先在Mainifest文件里面对要启动的Activity添加一个过滤器. 网页 ...

  4. Vue一个案例引发「动画」的使用总结

    项目开发中动画有着很重要的作用,而且也是用到的地方非常多,例如:鼠标的进入离开,弹窗效果,组件的显示隐藏,列表的切换等等,可以说我们网页上的动画无处不在,也有人说了,这些东西也可以不使用动画. 对,你 ...

  5. MySQL游标循环取出空值的BUG

    早上同事要我写个MySQL去除重复数据的SQL,想起来上次写过一篇MySQL去除重复数据的博客,使用导入导出加唯一索引实现的,但是那种方式对业务影响较大,所以重新写一个存储过程来删重复数据,这一写就写 ...

  6. Windows 更快捷方便的安装软件,命令提示符上安装 Chocolatey

    在命令提示符上安装 Chocolatey @powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-o ...

  7. Linux PXE无人值守网络装机

    Linux PXE无人值守网络装机 一.实验环境: 2台Linux系统(RHEL6.5版本),1台作为:PXE远程安装服务器(安装dhcp服务.ftp服务.tftp服务),另1台作为:客户端(未装RH ...

  8. Spark-RDD之Partition源码分析

    概要 Spark RDD主要由Dependency.Partition.Partitioner组成,Partition是其中之一.一份待处理的原始数据会被按照相应的逻辑(例如jdbc和hdfs的spl ...

  9. 跳跳棋[LCA+二分查找]-洛谷1852

    传送门 这真是一道神仙题 虽然我猜到了这是一道LCA的题 但是... 第一遍看题,我是怎么也没想到能和树形图扯上关系 并且用上LCA 但其实其实和上一道lightoj上的那道题很类似 只不过那时一道很 ...

  10. Spring Cloud:Security OAuth2 自定义异常响应

    对于客户端开发或者网站开发而言,调用接口返回有统一的响应体,可以针对性的设计界面,代码结构更加清晰,层次也更加分明. 默认异常响应 在使用 Spring Security Oauth2 登录和鉴权失败 ...