Desc:Go sync 包的使用方法,sync.Mutex,sync.RMutex,sync.Once,sync.Cond,sync.Waitgroup
尽管 Golang 推荐通过 channel 进行通信和同步,但在实际开发中 sync 包用得也非常的多。另外 sync 下还有一个 atomic 包,提供了一些底层的原子操作(这里不做介绍)
sync.waitGroup
WaitGroup总共有三个方法:Add(delta int),Done(),Wait()。简单的说一下这三个方法的作用。
Add:添加或者减少等待goroutine的数量
Done:相当于Add(-1)
Wait:执行阻塞,直到所有的WaitGroup数量变成0
golang中的同步是通过sync.WaitGroup来实现的.WaitGroup的功能:它实现了一个类似队列的结构,可以一直向队列中添加任务,当任务完成后便从队列中删除,如果队列中的任务没有完全完成,可以通过Wait()函数来出发阻塞,防止程序继续进行,直到所有的队列任务都完成为止.
WaitGroup的特点是Wait()可以用来阻塞直到队列中的所有任务都完成时才解除阻塞,而不需要sleep一个固定的时间来等待.但是其缺点是无法指定固定的goroutine数目.可能通过使用channel解决此问题。
sync.go
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i += 1 {
fmt.Println("for循环一次")
wg.Add(1)
go func(n int) {
fmt.Println("go开的协程")
// defer wg.Done()
defer wg.Add(-1)
EchoNumber(n)
}(i)
}
wg.Wait()
}
func EchoNumber(i int) {
time.Sleep(3e9)
fmt.Println(i)
}
运行结果:
for循环一次
for循环一次for循环一次
for循环一次
for循环一次
go开的协程
go开的协程
go开的协程
go开的协程
go开的协程
2
1
3
4
0
问题:
为什么输出就等了三秒 就全部输出了?
for先执行完五次循环 因为go func是异步执行,所以稍后打印出来。
并且是五个go func同时执行(5个同时执行,每个用3s,总时间就是3s)