先聊原生的 sync.Pool
要介绍gpool对象复用池之前,大家有必要先了解一下go原生提供的sync.pool。
简单来说sync.pool就是:临时对象池
其作用是:保存和复用临时对象,减少内存分配,降低GC压力。
使用较为简单。 总的思路就是:搞一个池子,预先放入临时产生的对象,然后取出使用。
好了,有了上述这些基础概念后,我们再了解gpool就简单多了。
gpool 入门
概念
对象复用池 gpool (并发安全的)
将对象进行缓存复用,支持:过期时间、创建方法、销毁方法。
使用场景
需要支持定时过期对象的复用场景
gpool和sync.pool的对比:
- 两者都可以达到对象复用的目的,但是sync.pool的对象生命周期不支持过期时间(原因是sync.pool并不是cache)
- sync.pool设计的初衷是缓解GC的压力,sync.pool中的对象会在GC开始前全部清除
- sync.pool不支持对象的创建方法和销毁方法
基础使用
实例化
添加值
取值
过期后取值测试
package main import ( "fmt" "github.com/gogf/gf/container/gpool" "time" ) func main() { p := gpool.New(time.Second*2, nil) err := p.Put(1) if err != nil { panic(err) } res, _ := p.Get() fmt.Println("取值:", res) //取值成功:返回1 time.Sleep(time.Second * 3) res, err = p.Get() if err != nil { panic(err) //此处报错:panic: pool is empty } fmt.Println("3秒后取值:", res) }
打印结果
取值: 1 panic: pool is empty goroutine 1 [running]: main.main() /Users/wangzhongyang/go/src/gf-study/study/gpool/gpool.go:37 +0x1d9 exit status 2
创建和销毁
在实例化gpool的时候,可以自定义:创建和销毁方法
package main import ( "fmt" "github.com/gogf/gf/container/gpool" "github.com/gogf/gf/net/gtcp" "github.com/gogf/gf/os/glog" "time" ) func main() { // 自定义创建和销毁方法 p := gpool.New(time.Second*3, func() (interface{}, error) { // 创建方法 //return gtcp.NewConn("goframe.org:80") return gtcp.NewConn("www.baidu.com:80") }, func(i interface{}) { //销毁方法 glog.Println("过期销毁") i.(*gtcp.Conn).Close() }) //获得复用池连接 conn, err := p.Get() //注意:一定要做err判断 if err != nil { panic(err) } //发送 result, err := conn.(*gtcp.Conn).SendRecv([]byte("HEAD / HTTP/1.1\n\n"), -1) //注意:一定要做err判断 if err != nil { panic(err) } fmt.Println("result:", string(result)) // 丢回池中以便重复使用 p.Put(conn) // 休眠一段时间,查看销毁方法有没有执行 time.Sleep(time.Second * 4) }
TIPS:注意一定要做err判断,不然出现问题后不好定位问题。
打印结果
result: HTTP/1.1 302 Found Connection: keep-alive Content-Length: 17931 Content-Type: text/html Date: Sat, 28 May 2022 13:18:38 GMT Etag: "54d97487-460b" Server: bfe/1.0.8.18 2022-05-28 21:18:38.496 过期销毁
总结
以上就是 GoFrame gpool 对象复用池
的基础使用,以及如何自定义创建和销毁方法。
也通过和sync.pool的对比,了解到了两者的区别:sync.Pool
的生命周期不支持自定义过期时间,并且sync.Pool
不支持对象创建方法及销毁方法;而gpool
的特点就是弥补了这两点不足:不但支持自定义过期时间,也支持自定义创建方法和销毁方法。