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) }() }