转载请注明出处:https://blog.csdn.net/sublio/article/details/106503509
全系列目录:https://blog.csdn.net/sublio/article/details/106480267
sync.Once||sync.WaitGroup||sync.Pool
目录
sync.Once
-
只执行一次
-
开箱即用
var once synv.Once
once.Do(func() {fmt.Println("Once!")})
sync.WaitGroup
-
开箱即用
-
不应该复制。
-
有一个代表计数的字节数组类型的字段,该字段用4字节表示给定计数,4字节表示等待计数。
-
Add(a int):其中a可正可负,来改变给定计数的值。
-
Done():给定计数减1。
-
不能让给定计数的值变为负数,这样会引发一个运行时恐慌。
-
Wait():调用时检查给定计数的值,如果为0则该方法立即返回,如果大于0则该方法所在goroutine阻塞,同时等待计数加1,直到给定计数变为0,会唤醒所有因此被阻塞的goroutine,同时把等到计数清零。
-
一般用于协调多个goroutine的执行。
-
Add或者Done导致的给定计数清零唤醒的goroutine是上一次从0到正数再到现在清零为止程序执行到Wait的goroutine。
-
可以循环(从0到正数再到0为一次)使用。
临时对象池sync.Pool
-
可以看作存放临时值(把存在其中的称做对象值)的容器。
-
临时对象池的实例不应该被复制。
-
对垃圾回收友好:
-
垃圾回收的执行一般会使临时对象池中的对象值全部被移除。
-
即使我们永远不显式地从临时对象池取走某个对象值,该对象值也不会永远待在临时对象池中,它的生命周期取决于垃圾回收任务的下一次执行。
-
-
初始化的时候可以为唯一公开字段New赋值。
-
类型为func() interface{}。
-
在池子中无可用对象值的时候被调用(生成的对象值永远不会被放到池里)。
-
-
Put方法:把一个interface{}类型的值放置于持重。
-
把参数值存放到本地P的本地池中。
-
-
Get方法:从池中获取一个interface{}类型的值。
-
如果Put方法没有被调用过,且New没有被赋予一个非nil的函数,Get方法返回的一定是nil。
-
如果Get取到的对象值时池中的,就一定会把它从池中删除。
-
-
它会专门为每一个操作它的goroutine相关联的P建立本地池。
-
Get方法一般先尝试从本地P对应的本地私有池和本地共享池中获取;如果获取失败,则试图从其它P的本地共享池中获取一个对象值;如果依然失败,则寄希望于临时对象生成函数了。
-
每个P的本地共享池中的所有对象值都是在当前临时对象池的范围内共享的,它们随时可能会被偷走。
-
参考文档
《Go并发编程实战(第2版)》——郝林