3. sync.Pool 原理
sync.Pool 是 Go 语言提供的内置对象池,开箱即用。sync.Pool 的原理非常简单,只有两个方法,Get 和 Put。Get 方法用于获取对象,Put 方法用于放回对象。
sync.Pool 的内部结构如下:
type Pool struct {
noCopy noCopy
local unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
localSize uintptr // size of the local array
localLen int32
victim unsafe.Pointer // local from previous cycle
victimSize uintptr // size of victims array
victimLen int32
New func() interface{}
}
sync.Pool 内部有两个指针,local 和 victim,分别用于存储本地的对象和上一轮的对象。local 和 victim 都是 unsafe.Pointer 类型,实际类型是 [P]poolLocal,P 为 CPU 核心数。
3.1 sync.Pool 的 Get 方法
sync.Pool 的 Get 方法用于获取对象,其原型如下:
func (p *Pool) Get() interface{}
Get 方法的实现非常简单,只有两个步骤:
- 获取当前 CPU 的 ID
- 从 local 中获取对象,如果 local 中不存在,则从 victim 中获取对象,如果 victim 中也不存在,则调用 New 方法创建对象
3.2 sync.Pool 的 Put 方法
sync.Pool 的 Put 方法用于放回对象,其原型如下:
func (p *Pool) Put(x interface{})
Put 方法的实现非常简单,只有两个步骤:
- 获取当前 CPU 的 ID
- 将对象放回 local 中
4. sync.Pool 的使用
sync.Pool 的使用非常简单,直接声明变量即可,不需要初始化。sync.Pool 的声明如下:
var pool = sync.Pool{}
sync.Pool 的操作如下:
pool.Get() // 获取对象
pool.Put() // 放回对象
5. sync.Pool 的注意事项
- sync.Pool 不能在创建后再进行复制操作。
- sync.Pool 与其他结构不同,它不是一个结构体,因此我们在声明的时候只需要声明变量即可,不需要初始化。