纯技术

Go 设计模式:对象池模式

Object pool Pattern, 对象被预先初始化并存储于对象池中,当需要时,客户端可以从对象池中请求一个对象并使用,然后将其返回对象池中 组成: 对象池: 类,主要用于维护可用对象的列表和已从对象池中请求的对象集合 客户端:调用对…

3 分钟阅读
精选技术记录
持续迭代更新
Share

什么是对象池模式

Object pool Pattern, 对象被预先初始化并存储于对象池中,当需要时,客户端可以从对象池中请求一个对象并使用,然后将其返回对象池中

组成:

  • 对象池: 类,主要用于维护可用对象的列表和已从对象池中请求的对象集合
  • 客户端:调用对象池中被池化的对许
  • 可重用池:用于判断对象池是否可重用

使用场景

  • 系统资源受限,需要提高内存管理效率
  • 需要创建大量的对象
  • 当对象是不可变对象
  • 短时间内连续创建和销毁大量对象

实现

go中的sync.Pool 实现了对象池,但其目的是为了优化GC, sync.Pool的存储对象随时可能被垃圾回收

  • 定义资源以及相关变量,并且初始化资源
//资源类
type Resource struct {
   reusable int
}

//初始化资源对象
//模拟缓慢的资源访问,例如,TCP 连接等
func NewResource(id int) *Resource {
   time.Sleep(500 * time.Millisecond)
   return &Resource{reusable: id}
}

//模拟资源耗时
func (r *Resource) Do(workId int) {
   time.Sleep(time.Duration(rand.Intn(5)) * 100 * time.Millisecond)
   log.Printf("using resource #%d finished work %d finish\n", r.reusable, workId)
}

  • 创建一个指定大小的对象池
//对象池
type Pool chan *Resource

//并发创建资源对象,节省资源对象初始化时间
func New(size int) Pool {
   p := make(Pool, size)
   wg := new(sync.WaitGroup)
   wg.Add(size)
   for i := 0; i < size; i++ {
      go func(reusable int) {
         p <- NewResource(reusable)
         wg.Done()
      }(i)
   }
   wg.Wait()
   return p
}

  • 基于通道获取对象池中的资源对象
//从获取对象池获取对象
func (p Pool) GetResource() (r *Resource, err error) {
   select {
   case r := <-p:
      return r, nil
   case <-time.After(getResMaxTime):
      return nil, ErrGetResTimeout
   }
}

  • 将资源返回对象池
//将资源返回到资源池
func (p Pool) GiveBackResource(r *Resource) error {
   if p == nil {
      return ErrPoolNotExist
   }
   p <- r
   return nil
}


本文同步自掘金

如果发现内容有误或需要更新,请访问掘金原文进行查看。

Share

如果这类内容对你有帮助

这里放一个阿里云 AIGC 活动入口。只有在你本身就有相关需求时,再通过它了解即可;如果产生推广收益,我会优先用于支付服务器、域名和网站维护费用。

看看阿里云 AIGC 活动

相关文章

2025年8月21日

为什么有的人学了很多年的编程,还是只会【增删改查】?

为什么你写了多年代码,技术栈还停留在"增删改查"? 我们不妨从一个常见的开发者画像开始:工作数年,日常任务是理解需求、实现业务逻辑、提供数据接口。在熟悉的框架下,每天熟练地进行着数据库的增、删、改、查(CURD)操作,周而复始。 这套流程看…

2023年12月21日

Golang-常用限流算法实现

常用的限流算法有一下4中实现方式: 令牌桶 漏桶 计数器 滑动窗口 令牌桶以恒定的速度向桶里加入令牌,桶满了则不再加入令牌。当服务收到请求时尝试从桶中取出一个令牌,如果可以获取到令牌,则继续执行后续的业务,否则返回超限错误码或对应的错误页面…

2023年12月21日

go-zero 使用 Consul 作为注册中心

go-zero 默认使用etcd作为注册中心,如果我们的业务使用的consul, 可以使用zero-contrib中的consul包进行替代 文件位置:ect/**.yaml 增加consul配置 服务启动后即可在conusl/ui上查看到…