在Go语言中,使用sync.Pool可以充分利用对象的复用,避免频繁地申请分配内存,以达到提升程序的性能的目的。
其中,sync.Pool的new函数是一个可选的函数类型,当不能从池中获取对象时,会调用该函数创建一个新的对象。其定义如下:
type Pool struct {
// ...
New func() interface{}
}
可以看出sync.Pool的new函数必须返回一个interface{}类型的对象,即一个新创建的对象,以便被放入池中等待复用。
当尝试从sync.Pool中获取对象时,若池中没有可用的对象,就会调用sync.Pool的New函数创建一个新的对象放入池中,这个过程可以理解为对象池的“初始化”。
示例代码如下:
package main
import (
"fmt"
"sync"
)
type Person struct {
Name string
Age int
}
func main() {
pool := &sync.Pool{
New: func() interface{} { // 当池为空时,调用该函数创建新实例
return &Person{"Li Lei", 11} // 创建一个新对象
},
}
// 从对象池中获取一个实例
p1 := pool.Get().(*Person)
fmt.Println(p1) // &{Li Lei 11}
// 将实例放回对象池中
pool.Put(p1)
// 再从对象池中获取一个实例,此时已有对象,直接返回对象池中的实例,不再调用 New 函数
p2 := pool.Get().(*Person)
fmt.Println(p2) // &{Li Lei 11}
}
上述代码中,我们定义了一个sync.Pool类型的pool对象,并将其New函数定义为返回一个Person类型的实例指针。
在主函数中,我们首先通过sync.Pool对象的Get函数从池中获取一个对象,由于此时池中还没有可用的对象,因此会调用New函数创建一个新的对象,然后返回该对象的指针。接着,我们使用sync.Pool对象的Put函数将该对象放回池中,以便后续复用。
最后,我们再次使用sync.Pool对象的Get函数从池中获取一个对象,此时由于池中已经有了可用的对象,因此不需要再调用New函数,直接返回池中的对象即可。