在上一篇文章里面我们介绍了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对象了。
还没有评论,来说两句吧...