有缓冲通道就是在有能力保留数据的通道,那么通道在满的时候或者通道是空的时候,存数据和取数据就会发生阻塞
package main import ( "fmt" "time" ) func main() { ch := make(chan int, 3) //创建一个有缓冲的通道 fmt.Printf("len(ch) = %d, cap(ch)=%d ", len(ch), cap(ch))//len(ch) = 0, cap(ch)=3 go func() { for i := 0; i< 3; i++{ fmt.Println("子协程:i = ", i) ch <- i //往通道里写内容 fmt.Printf("子协程len(ch) = %d, cap(ch)=%d ", len(ch), cap(ch)) } }() time.Sleep(2*time.Second) for i:=0;i<3;i++ { num := <-ch //读通道内的内容,没有内容则阻塞, fmt.Println("主协程: num = ", num) } }
执行的结果
len(ch) = 0, cap(ch)=3 子协程:i = 0 子协程len(ch) = 1, cap(ch)=3 子协程:i = 1 子协程len(ch) = 2, cap(ch)=3 子协程:i = 2 子协程len(ch) = 3, cap(ch)=3 主协程: num = 0 主协程: num = 1 主协程: num = 2
在主协程等待的2秒内,子协程完全可以进行3个值的写入,因为循环只有3次,所以才会看到这样的结果,但如果主协程和子协程都循环10次呢
len(ch) = 0, cap(ch)=3 子协程:i = 0 子协程len(ch) = 1, cap(ch)=3 子协程:i = 1 子协程len(ch) = 2, cap(ch)=3 子协程:i = 2 子协程len(ch) = 3, cap(ch)=3 子协程:i = 3 主协程: num = 0 主协程: num = 1 主协程: num = 2 主协程: num = 3 子协程len(ch) = 0, cap(ch)=3 子协程:i = 4 子协程len(ch) = 0, cap(ch)=3 子协程:i = 5 子协程len(ch) = 1, cap(ch)=3 子协程:i = 6 子协程len(ch) = 2, cap(ch)=3 子协程:i = 7 子协程len(ch) = 3, cap(ch)=3 子协程:i = 8 主协程: num = 4 主协程: num = 5 主协程: num = 6 主协程: num = 7 主协程: num = 8 子协程len(ch) = 0, cap(ch)=3 子协程:i = 9 子协程len(ch) = 0, cap(ch)=3 主协程: num = 9
因为是并发的执行,所以在每次执行的结果并不是完全一样的