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

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

先聊原生的 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的特点就是弥补了这两点不足:不但支持自定义过期时间,也支持自定义创建方法和销毁方法。

相关文章
|
3月前
|
NoSQL Redis
Lettuce的特性和内部实现问题之在同步调用模式下,业务线程是如何拿到结果数据的
Lettuce的特性和内部实现问题之在同步调用模式下,业务线程是如何拿到结果数据的
|
3月前
|
存储 设计模式 Java
Go - 使用 sync.Pool 来减少 GC 压力
Go - 使用 sync.Pool 来减少 GC 压力
64 0
|
6月前
|
缓存 Java Go
浅谈Golang对象池sync.pool
浅谈Golang对象池sync.pool
78 0
|
存储 缓存 安全
Golang 语言临时对象池 - sync.Pool
Golang 语言临时对象池 - sync.Pool
54 0
|
存储 缓存 Java
Sync.Pool无锁ringbuffer队列+双向链表构建高性能缓存池
Sync.Pool无锁ringbuffer队列+双向链表构建高性能缓存池
|
缓存 Java 测试技术
为何Gin使用Sync.Pool呢?到底解决框架本身什么性能瓶颈呢?
为何Gin使用Sync.Pool呢?到底解决框架本身什么性能瓶颈呢?
通过multiprocessing的Pool类来控制进程池
通过multiprocessing的Pool类来控制进程池
106 0
通过multiprocessing的Pool类来控制进程池
|
存储 算法 Unix
bthread源码剖析(四): 通过ParkingLot实现Worker间任务状态同步
通过之前的文章我们知道TaskGroup(以下简称TG)是在死循环等待任务,然后切换栈去执行任务。在当前TG没有任务的时候会进行“工作窃取”窃取其他TG的任务。在没有任务的时候TG会“休眠”,当任务出现的时候被唤醒然后消费。
323 0