持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
先聊原生的 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
的特点就是弥补了这两点不足:不但支持自定义过期时间,也支持自定义创建方法和销毁方法。
相关推荐
如果你想了解更多关于sync.pool的内容,大家可以直接查看这篇文章:由浅入深聊聊Golang的sync.Pool,整理的非常好。
最后
感谢阅读,欢迎大家三连:点赞、收藏、投币(关注)!!!