Golang
goroutine是Go语言强大的特性之一,合理的利用它才能发挥最大的价值数组
一、经调查
发现初学者通常会犯如下错误使用goroutine多线程
func goroutineRun(values []int) { for value := range values { go value.test() } }
或者使用闭包调用闭包
func goroutineRun(values []int) { for value := range values { go func() { fmt.Println(value) }() } }
这2段代码其实是遍历数组的全部变量。因为闭包只是绑定到这个value变量上,并无被保存到goroutine栈中,因此以上代码极有可能运行的结构都输出为切片的最后一个元素。由于这样写会致使for循环结束后才执行goroutine多线程操做,这时候value值只指向了最后一个元素。这样的结果不是咱们所但愿的,并且还会产生并发的资源抢占冲突因此是很是不推荐这样写的。并发
二、解决方法
goroutine的正确写法线程
for val := range values { go func(val interface{}) { fmt.Println(val) }(val) }
在这里将 val 做为一个参数传入 goroutine 中,每一个 val 都会被独立计算并保存到 goroutine 的栈中,从而获得预期的结果。code
另外一种方法是在循环内定义新的变量,因为在循环内定义的变量在循环遍历的过程当中是不共享的,所以也能够达到一样的效果:blog
for i := range valslice { val := valslice[i] go func() { fmt.Println(val) }() }