package main import ( "fmt" "time" ) func consumer(cname string, ch chan int) { //可以循環 for i := range ch 來不斷從 channel 接收值,直到它被關閉。 for i := range ch { fmt.Println("consumer-----------", cname, ":", i) } fmt.Println("ch closed.") } func producer(pname string, ch chan int) { for i := 0; i < 4; i++ { fmt.Println("producer--", pname, ":", i) ch <- i } } func main() { //用channel來傳遞"產品", 不再需要自己去加鎖維護一個全局的阻塞隊列 ch := make(chan int) go producer("生產者1", ch) go producer("生產者2", ch) go consumer("消費者1", ch) go consumer("消費者2", ch) time.Sleep(10 * time.Second) close(ch) time.Sleep(10 * time.Second) } for i := range ch { fmt.Println("consumer-----------", cname, ":", i) } 這個也可以改成:LOOP: for { select { case i,ok:=<-ch: if ok { fmt.Println("consumer--------", cname, ":", i) } else { break LOOP } } } //注意: i := <- ch 從空的channel中讀取數據不會panic, i讀取到的值是0, 如果channel是bool的,那么讀取到的是false //判斷channel是否關閉,可以使用像上面的ok pattern channel 本身就是並發安全的。