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

相关文章
相关标签/搜索