通用对象池ObjectPool的一种简易设计和实现方案

简介:

对象池,最简单直接的作用当然是通过池来减少创建和销毁对象次数,实现对象的缓存和复用。我们熟知的线程池、数据库连接池、TCP连接池等等都是非常典型的对象池。

一个基本的简易对象池的主要功能实现我认为应该至少包括以下三点:

1、对象的分配、销毁等管理策略

2、线程安全

3、性能

按照主要的常用功能,我们大致可以抽象出以下泛型接口IObjectPool<T>:

IObjectPool

 

具体实现这个接口的时候,考虑到线程安全,同时为了降低线程安全控制的种种风险,我们使用framework4.0中提供的线程安全容器,示例代码中选择非常适合这种场景的线程安全队列ConcurrentQueue(时间和空间复杂度都非常合适):

ObjectPool

 

其中,GetObject方法即对象的获取至少有两种策略:

1、悲观对象创建策略
这种策略在获取对象时,“悲观”地认为当对象池中暂无可用对象时,等待是会发生很久时间的,必须保证能够返回一个可用对象,所以不如去掉等待直接创建一个对象返回。虽然并发较高的场景下这有可能造成系统中对象总数暂时超出了最大对象数量限制,但好处是我们可以保证系统有足够的对象可用,不会因为没可用对象或等待创建可用对象而使上层逻辑受阻。
对于对象超过最大对象个数限制的情况,我们完全可以对外再暴露一个接口方法(示例为TryTrimToMax),当系统并发压力减轻时,可调用该方法清理多余的对象。
上面ObjectPool示例代码中我们采取的就是悲观创建对象的方案。

 

2、乐观对象创建策略

这种策略“乐观”地认为,当对象池中暂无可用对象时,所有对象的消费者会在用完对象后及时的返回对象池中。
如果对象池中无可用对象,那么当前请求者可能会选择Sleep或者Wait或WaitOne等方式等待。如果更乐观的话,还可以采用类似lock-free的方式多尝试去获取对象(不完全是CAS的那种lock-free),直到获取对象为止。
这种方式的优点显而易见,它的空间使用率高,不会造成对象超过最大上限。但它的缺点也很明显,在一个高并发的可用对象已经供不应求的环境下,这种策略多数实现都不是wait-free的,没有获取到对象的请求调用只能排队等待,这就极大地降低了系统吞吐量,原来的对象池是为了提高性能的,现在则成了系统性能瓶颈的重要原因。

上述示例代码中,泛型参数T有where限制,可通过Func委托间接去掉这个限制,当然构造函数会略微变得复杂:

ObjectPool

 

可通过下列代码进行测试验证:

ObjectPoolTest

 

本文的对象池实现较为简洁,只有基本的存取功能,其他功能如对象的销毁等可以继续扩展。还要感慨下幸好有了线程安全容器,果然可以成倍地提高生产效率,而且代码更加简洁优雅。






本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/p/Design-And-Implement-A-Simple-ObjectPool.html,如需转载请自行联系原作者

目录
相关文章
|
1月前
|
存储 NoSQL 数据处理
组合和继承怎么集成一个性能较好的项目
组合与继承是面向对象编程的核心概念,前者通过对象间关联实现高效解耦,后者则重用代码以节省空间和内存。组合常用于现代项目,利用代理与依赖注入简化代码管理;而继承简化了子模块对父模块资源的应用,但修改会影响整体。随着分层解耦及微服务架构如SpringCloud的出现,这些技术进一步优化了数据处理效率和服务响应性能,尤其在分布式存储与高并发场景下。同步异步调用、Redis分布式应用等也广泛运用组合与继承,实现代码和内存空间的有效复用。
|
4月前
|
设计模式 缓存 Java
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
|
4月前
|
存储 安全 Java
Java集合框架核心组件理解这些基础类型能优化代码效率。
【6月更文挑战第21天】Java集合框架核心组件:ArrayList快速随机访问,适合大量查找;LinkedList擅于插入删除,不适于随机访问;HashMap是键值对存储,O(1)查找删除。选择取决于应用场景:频繁访问选ArrayList,频繁增删选LinkedList,键值查找选HashMap。理解这些基础类型能优化代码效率。
31 1
|
3月前
|
设计模式 存储 缓存
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
45 0
|
5月前
|
设计模式 缓存 安全
分析设计模式对Java应用性能的影响,并提供优化策略
【4月更文挑战第7天】本文分析了7种常见设计模式对Java应用性能的影响及优化策略:单例模式可采用双重检查锁定、枚举实现或对象池优化;工厂方法和抽象工厂模式可通过对象池和缓存减少对象创建开销;建造者模式应减少构建步骤,简化复杂对象;原型模式优化克隆方法或使用序列化提高复制效率;适配器模式尽量减少使用,或合并多个适配器;观察者模式限制观察者数量并使用异步通知。设计模式需根据应用场景谨慎选用,兼顾代码质量和性能。
47 0
|
5月前
|
Kubernetes 网络协议 应用服务中间件
K8S管理核心资源的三种基本方法
K8S管理核心资源的三种基本方法
50 0
|
SQL 消息中间件 缓存
12种接口优化的通用方案
12种接口优化的通用方案
221 0
|
存储 缓存 安全
通用缓存存储设计实践
通用缓存存储设计实践
4667 3
通用缓存存储设计实践
优化对象变高效
没有优化过的对象,不足以看出C++的优势
|
XML JSON 前端开发
优化封装方案实现| 学习笔记
快速学习优化封装方案实现。
优化封装方案实现| 学习笔记