对象池简单来说就是一种为对象提供可复用能力的软件设计思路。我们常说有借有还,再借不难,而对象池就是通过借和还这样两个动作来保证对象可以被重复使用,从而节省频繁创建对象的性能开销。对象池最常用的场景是游戏设计,因为在游戏中大量存在着可复用的对象,源源不断的子弹出现并不是循环再生的。在数据库中存在着被称为连接池的东西,每当出现数据库无法连接的情况时,经验丰富的开发人员往往会先检查连接池是否满了,这其实就是对象池模式在特定领域的具体实现。因此对象池本质上就是负责一组对象创建和销毁的容器。 对象池最大的优势是可以自主地管理池子内的每个对象,决定它们是需要被回收还是可以重复使用。我们都知道创建一个新对象需要消耗一定的系统资源,一旦这些对象可以重复地使用就可以节省系统资源开销,这对提高系统性能会非常有帮助。下面的代码实微软官方文档实现的一个简单的对象池:
public class objectpool<t> : iobjectpool<t>{private func<t> _instancefactory;private concurrentbag<t> _instanceitems;public objectpool(func<t> instancefactory){_instancefactory = instancefactory ?? throw new argumentnullexception(nameof(instancefactory));_instanceitems = new concurrentbag<t>();}public t get(){t item;if (_instanceitems.trytake(out item)) return item;return _instancefactory();}publ奇函数加偶函数ic void return(t item){_instanceitems.add(item);}}
在.net core
中微软已经为我们提供了对象池的实现,即microsoft.extensions.objectpool
。它主要提供了三个核心的组件,分别是objectpool
、objectpoolprovider
和ipooledobjectpolicy
。objectpool
是一个抽象类,对外提供了get和return两个方法,这就是所谓的有借有还。objectpoolprovider
同样是一个抽象类,它的职责就是创建objectpool,它提供了两个create方法,两者的区别是无参数版本本质上使用的是defaultpooledobjectpolicy
。它和defaultobjectpool
、defaultobjectpoolprovider都是微软提供的默认实现,ipooledobjectpolicy可以为不同的对象池定义不同的策略,来决定对象如何借、是否可以还。defaultobjectpool内部使用objectwrapper[]来管理对象,objectwrapper[]的大小等于 maximumretained-1,默认情况下maximumretained等于environment.processorcount * 2
,这里主要用到了interlocked.compareexchange()
方法,
具体代码如下:
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) { } } }}
这里用到interlocked.compareexchange()
方法,get()方法将items[i].element
和null
进行交换,将指定元素设为 null 并返回原始值。return()方法将items[i].element
和obj交换后的值不为 null,表示指定元素已经归还,这个方法只有在第一个参数和第三个参数相等时才会发生交换。
说了这么多,我们来看一下对象池具体的用法:
var rvice = new rvicecollection();//使用defaultobjectpoolproviderrvice.addsingleton<objectpoolprovider, defaultobjectpoolprovider>();//使用默认策略rvice.addsingleton<objectpool<foo>>(rviceprovider =>{ var objectpoolprovider = rviceprovider.getrequiredrvice<objectpoolprovider>(); return objectpoolprovider.create<foo>();});//使用自定义策略rvice.addsingleton<objectpool<foo>>(rviceprovider =>{ var objectpoolprovider = rviceprovider.getrequiredrvice<objectpoolprovider>(); return objectpoolprovider.create(new fooobjectpoolpolicy());});var rviceprovider = _rvice.buildrviceprovider();var objectpool = _rviceprovider.getrvice<objectpool<foo>>();//有借有还,两次是同一个对象var item作文介绍自己1 = objectpool.get();objectpool.return(item1);var item2 = objectpool.get();asrt.areequal(item1, item2);//true//有借无还,两次是不同的对象var item3 = objectpool.get();var item4 = objectpool.get();asrt.areequal(item3, item4);//fal
上面的代码中foo和fooobjectpoolpolicy是两个工具类:
public class foo{ public string id { get; t; } public datetime? createdat { get; t; } public string createdby { get; t; }}public class fooobjectpoolpolicy : ipooledobjectpolicy<foo>{ public foo create() { return new foo() { id = guid.newguid().tostring("n"), createdat = datetime.now, createdby = "zs" }; } public bool return(foo obj) { return true; }}
tip:当你需要控制对象池内的对象如何被创建二级计算机成绩查询的时候,你可以考虑实现自定义的ipooledobjectpolicy<t>
,反之defaultpooledobjectpolicy<t>
实现完全可以满足你的使用。
实现对象池可以考虑concurrentbag
、stack、queue
以及blockingcollection
等多种数据结构,而微软在.net core 中已经为我们实现了一个简单的对象池,大多数情况下,我们只需要定义自己的ipooledobjectpolicy
去决定对象应该怎么样借、怎么样还。总之游戏世界里的 gameobject
、数据库里的连接池,都是对象池模式在各自领域中的具体实现。
tip:对象池是一种通过复用对象来减少资源开销进而实现提高系统性能的软件设计模式,其核2014年立冬心是控制容器内对象的生命周期来规避系统的主动回收,从对象池中借出的对象必须要及时归还,否则会造成对象池中没有可用资源。
到此这篇关于 .net core 中对象池 object pool的使用的文章就介绍到这了,更多相关 .net core 中对象池 内容请搜索www.887免费医学生551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!
本文发布于:2023-04-03 22:06:28,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/10c516a1ef7c63d5ef55f5d0637bebf9.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:.NET Core 中对象池 Object Pool的使用.doc
本文 PDF 下载地址:.NET Core 中对象池 Object Pool的使用.pdf
留言与评论(共有 0 条评论) |