ObjectPool 对象池设计模式
2024-08-29 19:55:26
Micosoft.Extension.ObjectPool
源码架构、模式分析:
三大基本对象:
- ObjectPool抽象类
- ObjectPoolProvider抽象类
- IPooledObjectPolicy接口
ObjectPool的默认实现是DefaultPool,对象池的创建由ObjectPoolProvider抽象类的默认实现DefaultObjectPoolProvider类实现。
public class DefaultObjectPoolProvider : ObjectPoolProvider
{
/// <summary>
/// The maximum number of objects to retain in the pool.
/// </summary>
public int MaximumRetained { get; set; } = Environment.ProcessorCount * 2;
/// <inheritdoc/>
public override ObjectPool<T> Create<T>(IPooledObjectPolicy<T> policy)
{
if (policy == null)
{
throw new ArgumentNullException(nameof(policy));
}
if (typeof(IDisposable).IsAssignableFrom(typeof(T)))
{
return new DisposableObjectPool<T>(policy, MaximumRetained);
}
return new DefaultObjectPool<T>(policy, MaximumRetained);
}
}
IPooledObjectPolicy接口有对应的抽象类及默认实现,对象池中的对象(也就是池对象)的创建或返回由此策略类来控制。
public override T Get()
{
var item = _firstItem;
if (item == null || Interlocked.CompareExchange(ref _firstItem, null, item) != item)
{
var items = _items;
for (var i = 0; i < items.Length; i++)
{
item = items[i].Element;
if (item != null && Interlocked.CompareExchange(ref items[i].Element, null, item) == item)
{
return item;
}
}
item = Create();
}
return item;
}
// Non-inline to improve its code quality as uncommon path
[MethodImpl(MethodImplOptions.NoInlining)]
private T Create() => _fastPolicy?.Create() ?? _policy.Create();
public override void Return(T obj)
{
if (_isDefaultPolicy || (_fastPolicy?.Return(obj) ?? _policy.Return(obj)))
{
if (_firstItem != null || Interlocked.CompareExchange(ref _firstItem, obj, null) != null)
{
var items = _items;
for (var i = 0; i < items.Length && Interlocked.CompareExchange(ref items[i].Element, obj, null) != null; ++i)
{
}
}
}
}
从整体的设计思路来说,提供者Provider用来提供具体的对象池,传入的参数也是策略类,而策略类则把控池对象的具体处理。dotnet core中很多源码的开发模式都是这种:通过Policy构建Provider,通过Provider创建最终的类。也就是说,只通过策略类来实现自定义扩展,这种架构可以借鉴和思考。
官方实现:
Object reuse with ObjectPool in ASP.NET Core
参考示例:
.NET Core 3.0之深入源码理解ObjectPool(二)
最新文章
- SQL SERVER 竖表变成横表
- 运行第一个PHP程序
- 微信小程序 不在以下合法域名列表中,请参考文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html
- 20145213《Java程序设计》第三周学习总结
- 如何使用Jquery自定义命名空间namespace
- python之文件操作
- 第22章 DLL注入和API拦截(2)
- memcached 系列2:memcached实例(转载)
- codeforces 339C Xenia and Bit Operations(线段树水题)
- Linux 系统文件夹结构
- php处理表单中的复选框问题以及js实现全选
- Android 性能测试——Memory Monitor 工具
- 保存html上传文件过程中遇到的字节流和字符流问题总结
- MongoDB投影有$slice如何只显示该字段
- Gradle 1.12用户指南翻译——第四十四章. 分发插件
- vue-router 用户登陆
- NodeJs命令
- Tools - Vim
- 从源码看Spring Boot 2.0.1
- java开发中的常见类和对象-建议阅读时间3分钟
热门文章
- 2019-9-9:渗透测试,基础学习,pydictor使用,sql盲注,docker使用,笔记
- Spring事务笔记
- STM32F103C8T6 在VSCode下使用Platform IO开发,基于库函数V3.5版本
- 01 jQuery配置、jQuery语法结构、jQuery对象与DOM对象的互相转换
- 【前端】之HTML5基础知识
- js基础-函数-var和let的区别
- VLAN实验5(在ensp上利用三层交换机实现VLAN间路由)
- 如何在导航条的button点击变换时,切换对应的控制器
- IDEA IntelliJ/ DataGrip 修改自动补全快捷键
- oc工程中oc、swift混编代码打包成静态framework踩坑笔记