同步之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===========同步