简介
临时对象池在go中对应sync.Pool类型,我们可以把sync.Pool当作存放临时值的容器,此容器是自动伸缩的、高效、线程安全的。
从临时对象池获取对象有两个途径,第一个是Get向池中Put对象,另一个是通过对Pool的公开字段New赋值一个类型为func() interface{}的方法,通过调用该方法获取到的值,该方法是默认调用的,当Pool中没有Put任何对象时,如果你设置了New字段,那么Get到的值就是调用New获取到的值。注意如果你Get到的对象是Put到Pool中的那么Get完之后就会把你Get到的对象从Pool中删除
临时池是对垃圾回收友好的,垃圾回收后,池中的对象将会被清除。
从临时池中Get到的对象是无序的。
例子
func main() {
//禁用gc,并保证在main函数执行结束前回复gc
defer debug.SetGCPercent(debug.SetGCPercent(-1))
var count int32
newFunc:=func() interface{}{
return atomic.AddInt32(&count,1)
}
pool:=sync.Pool{
New:newFunc,
}
v1:=pool.Get()
fmt.Printf("value 1: %v\n",v1)
pool.Put(10)
pool.Put(11)
pool.Put(12)
v2:=pool.Get()
fmt.Printf("value 2 :%v \n",v2)
//'垃圾回收临时对象池的影响
debug.SetGCPercent(100)
runtime.GC()
v3:=pool.Get()
fmt.Printf("value 3: %v\n",v3)
pool.New=nil
v4:=pool.Get()
fmt.Printf("value 4 : %v\n",v4)
}
输出结果为
value 1: 1
value 2 :10
value 3: 2
value 4 : <nil>
第一行value为1是因为pool中没有put任何对象,只是设置了New关键字,所以默认调用New。
第二行输出10是因为向Pool中put了对象。
第三行输出2是因为调用了垃圾回收后将pool中的对象都回收掉了所以调用New关键字生成的2
第四行为nil是因为pool中没有对象且New关键字也没有对应的生成方法所以只能为nil。