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

从图上可以明显看到和无缓冲通道的区别,无缓冲必须两个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. dsu on tree入门

    先瞎扯几句 说起来我跟这个算法好像还有很深的渊源呢qwq.当时在学业水平考试的考场上,题目都做完了不会做,于是开始xjb出题.突然我想到这么一个题 看起来好像很可做的样子,然而直到考试完我都只想出来一 ...

  2. SVN系列操作(二)&svn不显示图标的解决方法

    接着上一篇文章,我们继续来操作一下SVN: 有同学反馈,我在本地上看到不SVN的图标,先解决一下这个问题. svn不显示图标的解决方法: 1.WIN+R,输入regedit,打开注册表 2.找到HKE ...

  3. C# 用户控件之温度计

    本文以一个用户控件[User Control]实现温度计的小例子,简述用户控件的相关知识,以供学习分享使用,如有不足之处,还请指正. 概述 一般而言,用户控件[User Control],是在Visu ...

  4. Android Picasso最详细的使用指南

    Picasso 是Square 公司开源的Android 端的图片加载和缓存框架.Square 真是一家良心公司啊,为我们Android开发者贡献了很多优秀的开源项目有木有!像什么Rerefoit . ...

  5. SCSS 在项目中的运用

    最后一段时间一直在做一些网站或是CMS的项目,想用bootstrap,但是,设计那哥们说了,用什么都行,就不能用bootstrap,我去了个..... 无语中,逼着自己写.说实话,就是用bootstr ...

  6. c#二进制移位运算符 "<<"及">>","&","|","^"

    移位运算符 & :按位与,其实与&&逻辑运算符有一致的地方: | :按位或,同样与||有类似的地方. ~:按位取反 ^:按位异或 <<:左移运算符 >> ...

  7. iead2018创建JavaWe工程

    菜单栏中 File-> Project,弹出如下界面,选择 Java并勾选 Web Application 填写 Project Name 配置 tomcat 点击右上角的绿色的小锤子,然后打开 ...

  8. Got a packet bigger than‘max_allowed_packet’bytes错误的解决方法

    通常项目上线前都有一些初始化数据需要导入,在今天博客系统发布前我使用sqlyog工具远程登录服务器的Mysql数据库,执行sql脚本对初始数据进行导入的时候报错: Got a packet bigge ...

  9. C 存储类

    存储类定义 C 程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在它们所修饰的类型之前.下面列出 C 程序中可用的存储类: auto.register.static.extern auto ...

  10. hello随笔

    初次来到博客园,都试一下 我明白了,随笔就是博客咯.日记自对自己可见.再试试分类吧