当前位置: 首页 > 工具软件 > Golang-Pool > 使用案例 >

golang踩坑--sync.Pool能干嘛

广亮
2023-12-01

在项目库中看到有用到sync.Pool字段,很好奇具体的作用,简单学习了一下,写个小博客总结一下。

一、sync.Pool的作用

sync.Pool 可以看作一个存放临时对象的池,使用到该对象时,可以从pool里拿,不需要时就归还到pool里。

为什么需要sync.Pool?直接声明Object不可以吗?Golang明明是有GC的语言。
但其实,如果可以复用对象,就能大大节省对象创建和回收的开销,从而达到优化内存使用的目的。对大对象,频繁使用的对象来说,该优化很有必要。

二、sync.Pool的特性

首先,sync.Pool对象池中的对象并非永久存放,任何物品都可能在任意时间被移除。如果只有对象池拥有某个对象的引用,该对象就会被释放内存。

其次,sync.Pool作为sync包下的一个模块,也拥有多线程安全的特性。Pool中的对象可以被多个独立并行的客户端取用。sync.Pool还拥有在多个客户端之间分摊内存分配开销的机制。

最后,sync.Pool拥有自动扩容缩容的功能。同一类的对象官方推荐使用单例pool,同时,pool在第一次使用后不允许被拷贝

三、sync.Pool的使用

看源码

type Pool struct {
	// ...
	// New optionally specifies a function to generate
	// a value when Get would otherwise return nil.
	// It may not be changed concurrently with calls to Get.
	New func() any
}
func (p *Pool) Get() any
func (p *Pool) Put(x any)

sync.Pool 的使用非常简单,在获取物品时,应调用Get()方法,在归还物品时,使用Put()方法。在使用Pool前,应定义New的方法。在调用Get()方法且池中尚无物品时,会优先调用New的函数生成物品并返回,否则,Get()就会返回nil。
以下是一个例子:

//声明
objectPool *sync.Pool
//定义New函数
objectPool = &sync.Pool{
	New: func() interface{} {
	return &Object{}
}
//使用物品
obj := objectPool.Get().(*Object)
//归还物品
objectPool.Put(obj)

四、其他

关于sync.Pool机制更详细的说明可以看这篇博客

  • https://www.jianshu.com/p/8fbbf6c012b2
 类似资料: