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

相关文章
|
5月前
|
前端开发 JavaScript
ES2017 最佳特性 -- 数组中的异步函数以及共享缓冲区
ES2017 最佳特性 -- 数组中的异步函数以及共享缓冲区
|
5月前
|
NoSQL Redis
Lettuce的特性和内部实现问题之在同步调用模式下,业务线程是如何拿到结果数据的
Lettuce的特性和内部实现问题之在同步调用模式下,业务线程是如何拿到结果数据的
|
8月前
|
C++
C++程序对象动态建立和释放
C++程序对象动态建立和释放
59 1
|
8月前
|
C++
35对象的动态建立和释放
35对象的动态建立和释放
34 1
|
存储 缓存 安全
Golang 语言临时对象池 - sync.Pool
Golang 语言临时对象池 - sync.Pool
63 0
|
Linux
pmdk如何在线动态扩展pool大小
pmdk如何在线动态扩展pool大小
105 0
|
存储 缓存 Java
Sync.Pool无锁ringbuffer队列+双向链表构建高性能缓存池
Sync.Pool无锁ringbuffer队列+双向链表构建高性能缓存池
|
编译器 C语言 C++
【c++】 --- 对象的动态建立和释放
【c++】 --- 对象的动态建立和释放
52 0
|
C# Windows
.NET一个线程更新另一个线程的UI(两种实现方法及若干简化)
原文:.NET一个线程更新另一个线程的UI(两种实现方法及若干简化) 本片博文接上一篇:.NET多线程执行函数,给出实现一个线程更新另一个线程UI的两种方法。 Winform中的控件是绑定到特定的线程的(一般是主线程),这意味着从另一个线程更新主线程的控件不能直接调用该控件的成员。
1537 0
|
缓存
读源码长知识 | 动态扩展类并绑定生命周期的新方式
在阅读viewModelScope源码时,发现了一种新的方式。 协程需隶属于某 CoroutineScope ,以实现structured-concurrency,而 CoroutineScope 应
180 0