内容简介:写一个简单的程序,使得一个协程用来向channel中写如数据,一个用来读取数据。然后下面是三段代码,大家看之前可以小思考下运行结果,最好自己动手测试下。当然是阻塞的,写协程阻塞了,读协程只能干等着啊,这个问题好像有点(๑•ᴗ•๑)
写一个简单的程序,使得一个协程用来向channel中写如数据,一个用来读取数据。
import (
"fmt"
"strconv"
"testing"
)
/**
在这个示例中,我们有
- 一个message作为channel
- 一个协程用来发送消息
- 主协程用来接收消息
*/
func Test_message(t *testing.T) {
/**
声明一个长度为 1 的channel
*/
messages := make(chan string)
/**
该协程负责向channel发送数据,共发送五次
*/
go func() {
for i := 0; i < 5; i++ {
messages <- "Hello, 这是第 " + strconv.Itoa(i) + " 次传递消息"
}
}()
/**
读取channel中的数据,这是个阻塞的操作
*/
for i := 0; i < 5; i++ {
fmt.Println(<- messages)
}
}
代码样例
然后下面是三段代码,大家看之前可以小思考下运行结果,最好自己动手测试下。
假如向channel中写入数据时,设置1秒钟的延迟,那么读取channel数据的协程会阻塞吗?
import (
"fmt"
"strconv"
"testing"
"time"
)
/**
在这个示例中,我们的副协程在向channel中写入数据的时候,有一秒的延迟
然后我们发现控制台断断续续的打印出了内容
说明我们从channel中读取消息是个阻塞的行为
*/
func Test_message1(t *testing.T) {
/**
声明一个长度为 1 的channel
*/
messages := make(chan string)
/**
该协程每隔一秒向channel发送一个数据
*/
go func() {
for i := 0; i < 5; i++ {
time.Sleep(time.Second * 1)
messages <- "Hello, 这是第 " + strconv.Itoa(i) + " 次传递消息"
}
}()
/**
读取channel中的数据,这是个阻塞的操作
*/
for i := 0; i < 5; i++ {
fmt.Println(<- messages)
}
}
当然是阻塞的,写协程阻塞了,读协程只能干等着啊,这个问题好像有点(๑•ᴗ•๑)
如果给读协程设置一秒延迟,那么写协程会阻塞吗?
import (
"fmt"
"strconv"
"testing"
"time"
)
/**
在这个示例中,我们向channel中读取数据时,设置了一秒的延迟
然后我们发现控制台断断续续的打印出了内容
说明我们向channel中写入消息也是是个阻塞的行为
它受到channel容量的限制,如果channel容量满了,写操作就会阻塞协程
*/
func Test_message2(t *testing.T) {
/**
声明一个长度为一的channel
*/
messages := make(chan int)
/**
该协程每隔一秒向channel发送一个数据
*/
go func() {
for i := 0; i < 5; i++ {
messages <- i
fmt.Println("Hello, 这是第 " + strconv.Itoa(i) + " 次传递消息")
}
}()
/**
读取channel中的数据,这是个阻塞的操作
*/
for i := 0; i < 5; i++ {
<- messages
time.Sleep(time.Second * 1)
}
}
答案是会的,因为channel的容量是有限的,没有消费者的话,生产者是不能继续生产的。
如何给channel设置一个5的容积,那么下面程序的运行结果会是怎么样的?
import (
"fmt"
"strconv"
"testing"
"time"
)
/**
在这个示例中,我们创建了一个有缓存channel
大家可以自行执行以下,可以看到前面6次打印非常快,后面三次则是断断续续的
这就是有缓冲的channel,即使没有消费者,我们依旧可以向channel中写入数据,
直到容量达到上限
*/
func Test_message3(t *testing.T) {
/**
声明一个容量为5的channel
*/
messages := make(chan int, 5)
/**
该协程持续的尝试向channel中发送一个数据
*/
go func() {
for i := 0; i < 10; i++ {
messages <- i
fmt.Println("Hello, 这是第 " + strconv.Itoa(i) + " 次传递消息")
}
}()
/**
每隔一秒读取一次channel中的数据,这是造成channel内元素逐渐累积
*/
for i := 0; i < 5; i++ {
<- messages
time.Sleep(time.Second * 1)
}
}
答案是前面6次打印非常快,后面三次则是断断续续的
怎么样,是不是对协程和channel有了基本的认识了
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- PHP代码审计之入门实战
- Android 代码布局 —— 从入门到放弃(一)
- 由表生成代码:mybatis-generator入门
- VMProtect 3.3.1虚拟机&代码混淆机制入门
- 半小时入门Rust,这是一篇Rust代码风暴
- p5.js入门教程之小球动画示例代码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java编程思想
埃克尔 / 机械工业出版社 / 2007-5-1 / 79.00元
《Java编程思想(英文版•第4版)》内容简介:特色:1.适合初学者与专业人员的经典的面向对象的叙述方式;为更新的Java SE5/6的相关内容增加了新的示例和章节。2.测验框架显示程序输出。3.设计模式贯穿于众多示例中:适配器、桥接器、职责链、命令、装饰器、外观、工厂方法、享元、点名、数据传输对象、空对象、代理、单例、状态、策略、模板方法以及访问者。4.为数据传输引入了XML;为用户界面引入了S......一起来看看 《Java编程思想》 这本书的介绍吧!