同步之sync.Once && sync.WaitGroupgit
A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished. sync.WaitGroup只有3個方法,Add(),Done(),Wait()。 其中Done()是Add(-1)的別名。簡單的來講,使用Add()添加計數,Done()減掉一個計數,計數不爲0, 阻塞Wait()的運行。.net
其實 sync.WaitGroup 和 Java中的閉鎖是類似的。根據這個例子http://my.oschina.net/xinxingegeya/blog/345969, 使用Go的WaitGroupcode
package main import ( "fmt" "sync" "time" ) func main() { var start sync.WaitGroup var end sync.WaitGroup start.Add(1) //在main goroutine 添加計數器 +1 for i := 0; i < 10; i++ { end.Add(1) // 啓動一個goroutine時要加一 go func(n int) { defer end.Done() start.Wait() //首先wait,等待在main goroutine中發出的開始信號 time.Sleep(time.Duration(n) * time.Second) fmt.Printf("sleep %d seconds\n", n) }(10 - i) } t1 := time.Now().UnixNano() start.Done() //讓全部的goroutine 同一時刻開始工做,比如如發令槍一響,全部的運動員同時起跑 end.Wait() //等待全部的goroutine執行完成 fmt.Println("wait end, all goroutine finished...") t2 := time.Now().UnixNano() fmt.Printf("spend time %d\n", t2-t1) }
運行結果,對象
➜ wait git:(master) ✗ go run wait.go sleep 1 seconds sleep 2 seconds sleep 3 seconds sleep 4 seconds sleep 5 seconds sleep 6 seconds sleep 7 seconds sleep 8 seconds sleep 9 seconds sleep 10 seconds wait end, all goroutine finished... spend time 10000841348
從字面意思上來理解,就是僅且執行一次,相似於Java中的單例模式,只new一次對象。示例以下,blog
package main import ( "fmt" "sync" "time" ) func main() { var start sync.WaitGroup var end sync.WaitGroup start.Add(1) //在main goroutine 添加計數器 +1 var once sync.Once for i := 0; i < 10; i++ { end.Add(1) // 啓動一個goroutine時要加一 go func(n int) { defer end.Done() start.Wait() //首先wait,等待在main goroutine中發出的開始信號 once.Do(func() { time.Sleep(time.Duration(n) * time.Second) fmt.Printf("sleep %d seconds\n", n) }) }(10 - i) } t1 := time.Now().UnixNano() start.Done() //讓全部的goroutine 同一時刻開始工做,比如如發令槍一響,全部的運動員同時起跑 end.Wait() //等待全部的goroutine執行完成 fmt.Println("wait end, all goroutine finished...") t2 := time.Now().UnixNano() fmt.Printf("spend time %d\n", t2-t1) }
運行結果,get
➜ wait git:(master) ✗ go run wait.go sleep 1 seconds wait end, all goroutine finished... spend time 1004161371
===========END===========同步