009_golang的make(chan int)和make(chan int, 1)区别

make(chan int)和make(chan int, 1)的区别就是unbuffered和buffered的区别,下面进行详细解释:

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" 也可能是空,运行了好多次基本打印的都是空

  官方文档解释的区别:Channel: The channel's buffer is initialized with the specified buffer capacity. If zero, or the size is omitted, the channel is unbuffered.

  make(chan int) 是 unbuffered channel, send 之后 send 语句会阻塞执行,直到有人 receive 之后 send 解除阻塞,后面的语句接着执行。所以执行 c <- 0 时会阻塞,直到 <-c, 这时 a 已赋值。
  make(chan int, 1) 是 buffered channel, 容量为 1。在 buffer 未满时往里面 send 值并不会阻塞, 只有 buffer 满时再 send 才会阻塞,所以执行到 c <- 0 时并不会阻塞 fmt.Println(a) 的执行,这时 a 可能是 "hello world" 也可能是空, 看两个 goroutine 谁执行的更快,如下的代码:

package main
import "fmt"
func main() {
	var c = make(chan int, 1)
	var a string

	go func() {
		a = "hello world"
		<-c
	}()

	c <- 0
	c <- 1
	fmt.Println(a)
}

  如果在 fmt.Println(a) 之前加一些耗时操作,很有可能打印的还是 "hello world", 因为给 a 赋值的语句已经执行完了

package main
import "fmt"
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)
}

  

 

posted @ 2019-04-30 16:52  arun_python  阅读(959)  评论(0)    收藏  举报