在上一篇文章里面我们介绍了chan通道,但是大家发现没有这里通道来解决多线程的话,用起来就比较麻烦,所以官方推荐了一个sync.WaitGroup函数。这个函数我们怎么看待呢?其实就是相当于java里面的CountDownLatch。整个流程如下:
1、创建一个sync.WaitGroup对象 2、每启动一个线程,就向sync.WaitGroup对象数量+1 3、使用go启动子线程 4、子线程完毕之后,对标sync.WaitGroup对象完成done动作 5、主线程的sync.WaitGroup对象等待即可
根据上面的流程我们在go语言里面的实现示例如下:
1)创建一个sync.WaitGroup对象
var wg sync.WaitGroup
2)每启动一个线程,就把sync.WaitGroup对象数量+1
for i := 0; i < 100; i++ {
wg.Add(1)
}3)使用go启动子线程任务
go doAction(i, &wg)
4)在子线程执行完毕之后,指定done动作
func doAction(index int, wg *sync.WaitGroup) {
fmt.Println("doAction task no:" + strconv.Itoa(index))
defer wg.Done()
}5)主线程进行等待
wg.Wait()
以上示例的完整代码如下:
// demo1 project main.go
package main
import (
"fmt"
"strconv"
"sync"
)
func doAction(index int, wg *sync.WaitGroup) {
fmt.Println("doAction task no:" + strconv.Itoa(index))
defer wg.Done()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go doAction(i, &wg)
}
wg.Wait()
fmt.Println("all done")
}然后我们来看看结果:
是不是执行很方便?代码看起来也很直观。
备注:
1、这里的话我们子线程任务执行完毕之后,一定要使用wg.Done,不然多线程管理器会一直认为这个任务还在执行中。
2、这里的wg对象需要传对象的引用,不要直接传值,传值的话会直接报错,因为不是使用同一个wg对象了。


还没有评论,来说两句吧...