GoFrame gpool 对象复用池 | 对比sync.pool

3,520 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

先聊原生的 sync.Pool

要介绍gpool对象复用池之前,大家有必要先了解一下go原生提供的sync.pool。

简单来说sync.pool就是:临时对象池

其作用是:保存和复用临时对象,减少内存分配,降低GC压力。

使用较为简单。 总的思路就是:搞一个池子,预先放入临时产生的对象,然后取出使用

好了,有了上述这些基础概念后,我们再了解gpool就简单多了。

gpool 入门

概念

对象复用池 gpool (并发安全的)

将对象进行缓存复用,支持:过期时间、创建方法、销毁方法。

使用场景

需要支持定时过期对象的复用场景

gpool和sync.pool的对比:

  1. 两者都可以达到对象复用的目的,但是sync.pool的对象生命周期不支持过期时间(原因是sync.pool并不是cache)

  2. sync.pool设计的初衷是缓解GC的压力,sync.pool中的对象会在GC开始前全部清除

  3. 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,整理的非常好。

最后

感谢阅读,欢迎大家三连:点赞、收藏、投币(关注)!!!

8e95dac1fd0b2b1ff51c08757667c47a.gif