Go语言的有缓冲channel和无缓冲channel的区别,有一段很常见的代码。
package main
import (
"sync"
"time"
)
func main() {
// 没有缓冲的channel
c := make(chan string)
var wg sync.WaitGroup
wg.Add(2)
// 直接填充 foo 到 c 里面
go func() {
defer wg.Done()
c <- `foo`
fmt.Println("填充完毕执行。。。。")
}()
// 由于是没有缓冲区的,只有在发送方和接收方都准备就绪的时候通信才能成功
// 如果通道是无缓冲的,发送者将被阻塞,直到接收者接收到值。
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
println(`Message: `+ <-c)
}()
wg.Wait()
}
这里程序的执行结果是,可以看到channel的阻塞
Message: foo
填充完毕执行。。。。
我们再看一下有缓冲区程序的输出
package main
import (
"fmt"
"sync"
"time"
)
func main() {
c := make(chan string, 2)
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
c <- `foo`
fmt.Println("111")
c <- `bar`
fmt.Println("222")
}()
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
println(`Message: `+ <-c)
println(`Message: `+ <-c)
}()
wg.Wait()
}
111
222
Message: foo
Message: bar
有一个很形象的图片描述这个样子
这里只是一些浅显的理解。