Golang – Channel Unbuffered VS Buffered区别
参考文章:
- https://diiyw.com/2019/10/24/go-channel-buffer/
 - https://blog.wu-boy.com/2020/01/when-to-use-go-channel-and-goroutine/
 
在Go中我们make一个channel有两种方式,分别是有缓冲的 (buffered) 和没缓冲的 (unbuffered)
- Buffered channel 创建方式为 make(chan TYPE,SIZE)
– 如:make(chan string,2) 就是创建一个string类型,buffer大小为3的channel - Unbuffered channel创建方式为 make(chan TYPE)
– 如: make(chan string) 就是创建一个string 类型的channel,无需定义buffer大小 
Unbuffered 和 buffered channel的区别
- Unbuffered channel是channel发送和接收是同时发生的
– 如: ch := make(chan int) 如果没goroutine 读取接收者 <-ch 那么发送者 ch<- 就会一直塞着 - Buffered channel 只有列队满了才可能发生阻塞
 
【Unbuffered Channel的代码案例】

- 同步进行的,在读取channel会阻塞,直到goroutine当中发送数据到channel
 
func main() {
	ch := make(chan int)
	go func() {
		ch <- 42 // 发送操作
		fmt.Println("Sent value")
	}()
	value := <-ch // 接收操作
	fmt.Println("Received value:", value)
}- 以下是unbuffered channel,loop着接收来自channel的数据
 - 由于是同步进行的,所以必须一进就一出,如果读取的部分慢了,那么写入的部分就会卡着等待了
 
func main() {
	ch := make(chan int)
	// 启动一个 goroutine 来发送数据
	go func() {
		for i := 0; i < 5; i++ { // 循环发送5次数据
			ch <- i
			fmt.Println("Sent value:", i)
			time.Sleep(time.Second) // 睡眠1秒,模拟一些工作
		}
		close(ch) // 发送完成后关闭通道
	}()
	// 主 goroutine 接收数据
	for value := range ch {
		fmt.Println("Received value:", value)
	}
}【Buffered Channel的代码案例】

- 都是异步处理的,不会因为读取的数据慢了而阻塞
 - 如果channel满了,就会阻塞,必须等待channel腾出空位了之后才能继续往内发送数据
 
func main() {
	ch := make(chan int, 2) // 创建一个容量为 2 的缓冲通道
	ch <- 1 // 发送操作,不会阻塞
	fmt.Println("Sent value 1")
	ch <- 2 // 发送操作,不会阻塞
	fmt.Println("Sent value 2")
	go func() {
		ch <- 3 // 发送操作,此时会阻塞,直到有空位
		fmt.Println("Sent value 3")
	}()
	value1 := <-ch // 接收操作
	fmt.Println("Received value:", value1)
	value2 := <-ch // 接收操作
	fmt.Println("Received value:", value2)
	value3 := <-ch // 接收操作,解除阻塞
	fmt.Println("Received value:", value3)
}输出结果:
Sent value 1
Sent value 2
Received value: 1
Received value: 2
Sent value 3
Received value: 3
 ![]()
		Facebook评论