Go 提供了一个关键字go
用于执行并发操作的关键字 所以说Go从语言层面上就支持了并发
其中go 关键字启动的是一个协程这里并非线程 协程是轻量级的 有可能10几个协程下对应了5,6个线程go语言自动帮我们管理
其实和java中的线程池 我个人觉得还是很类似的
只不过java中的线程池有多种实现方式 如schedule single fix buffer 各有不同的使用场景
目前我还是不太清楚这种替我们管理线程的方式是好或不好 毕竟不是大牛 先用着再说吧
Goroutine - 协程
通过go关键字就可以直接启动一个协程
Channel - 协程间通信的通道
管道应该很好理解 就和Java里面的IO流管道式一个道理一边进一边出
在Go中 如果调用了内置函数close关闭之后 便无法再向管道中写入数据但是仍然可以继续读取数据
做汉堡包的人--简称厨师
比如麦当劳里面买汉堡包 厨师后台做好了一个汉堡包 如果是在一个比较大的麦当劳店里会有一台机器,厨师把汉堡放到机器中然后继续做自己的事,机器负责把这个做好的汉堡运送到前面的那个保温的透明箱子里 ,也就是我们每回点餐时都能看到的那个 里面放了很多汉堡 鸡腿 鸡块啥的 ,如果有人点了汉堡 前台收银员就会从这里面拿一个汉堡出来给顾客 然后继续做自己的事
这整个过程如果按照Go里面的说法就是完成了协程之间的通信 厨师就是协程1 前台收银员就是协程2 而中间所有的部分都是Channel
通过代码示例更容易懂
channel := make(chan int) 这样就声明了一个阻塞式的无缓冲的通道
chan 是关键字 代表我要创建一个通道
int则代表该通道所能接受的数据类型为int
那么如果有两个A,B两个协程 在放入和取出数据时都只能用int类型的数据进行通信
如 取数据 <- channel 放数据 channel <- 1
协程之间可以通过在通道中放入-取出数据的方式进行通信
用代码展示下无阻赛的Channel是如何在协程之间实现通信
示例 并发计算
package main import ( "fmt" ) func sum(arr []int,c chan int){ num := 0 for _,v := range arr { num += v } //放入数据到通道中 --- 如此一来 主协程中一发现通道中有数据就会立刻取出数据了 c <- num } func main() { //创建一个通信通道 c := make(chan int) slice := []int {1,2,3,4,5,6,7,8,9,10} //启动协程 1 go sum(slice[0:len(slice)/2],c) //启动协程 2 go sum(slice[len(slice)/2:],c) //阻塞式 接受来自 协程1,2的返回结果 num1, num2 := <- c, <- c fmt.Println(num1, num2, num1+num2) }
有疑问加站长微信联系(非本文作者)