同步之sync.Once && sync.WaitGroup

同步之sync.Once && sync.WaitGroupgit

sync.WaitGroup

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

sync.Once

從字面意思上來理解,就是僅且執行一次,相似於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===========同步

相關文章
相關標籤/搜索