弄懂了下面的這個例子你就懂了
package main
import "fmt"
func main() {
var c = make(chan int)
var a string
go func() {
a = "hello world"
<-c
}()
c <- 0
fmt.Println(a)
}
上面的例子會打印 "hello world"
如果改成 var c = make(chan int, 1) a 可能是 "hello world" 也可能是空,我運行了好多次基本打印的都是空
make(chan int) 是 unbuffered channel, send 之后 send 語句會阻塞執(zhí)行,直到有人 receive 之后 send 解除阻塞,后面的語句接著執(zhí)行。
所以執(zhí)行 c <- 0 時會阻塞,直到 <-c, 這時 a 已賦值。
make(chan int, 1) 是 buffered channel, 容量為 1。在 buffer 未滿時往里面 send 值并不會阻塞, 只有 buffer 滿時再 send 才會阻塞,所以執(zhí)行到 c <- 0 時并不會阻塞 fmt.Println(a) 的執(zhí)行,這時 a 可能是 "hello world" 也可能是空, 看兩個 goroutine 誰執(zhí)行的更快
我如果在 fmt.Println(a) 之前加一些耗時操作,很有可能打印的還是 "hello world", 因為給 a 賦值的語句已經(jīng)執(zhí)行完了
func main() {
var c = make(chan int, 1)
var a string
go func() {
a = "hello world"
<-c
}()
c <- 0
// 模擬耗時操作
sum := 0
for i := 0; i < 100000; i++ {
sum += i*23 + 45 - 7*4/2 - 99
}
fmt.Println(a)
}