当我们频繁创建删除大量对象的时候,对象的创建删除所造成的开销就不容小觑了。为了提高性能,我们往往需要实现一个对象池作为Cache:使用对象时,它从池中提取。用完对象时,它放回池中。从而减少创建对象的开销。

由于.net BCL库中并没有对象池的标准实现,因此需要我们自己去实现。好在实现功能简单的对象池并不麻烦,一般几十行代码就能实现。需要注意的一点是,对象池大多是需要支持多线程访问的,因此需要考虑线程安全问题。

在.Net 4.0后,BCL在System.Collections.Concurrent名字空间下引入了一系列线程安全的对象,微软甚至在MSDN上给了一个通过实现对象池的简单示例:How to: Create an Object Pool by Using a ConcurrentBag.

这个例子本身没有什么问题,但如果放在实际生产中就觉得有点简单过头了,一般还需要加上容量限制和重用时进行reset操作。这里我就稍微将其改了下:

 public class ObjectPool<T>
{
ConcurrentBag<T> buffer;
Func<T> createFunc;
Action<T> resetFunc; public ObjectPool(Func<T> createFunc, Action<T> resetFunc, int capacity)
{
Contract.Assume(createFunc != null);
Contract.Assume(capacity > ); this.buffer = new ConcurrentBag<T>();
this.createFunc = createFunc;
this.resetFunc = resetFunc; this.Capacity = capacity;
} public int Capacity { get; private set; }
public int Count { get { return buffer.Count; } } /// <summary>
/// 申请对象
/// </summary>
public T GetObject()
{
var obj = default(T); if (!buffer.TryTake(out obj))
return createFunc();
else
return obj;
} /// <summary>
/// 释放对象
/// </summary>
public void PutObject(T obj)
{
Contract.Assume(obj != null); if (Count >= Capacity) //超过容量了,不再需要
return; if (resetFunc != null)
resetFunc(obj); buffer.Add(obj);
}
}

需要注意的是,我这里的实现并没有完全确保Capacity的绝对性:当两个线程同时往一个即将到达上限的对象池中放置对象时,可能都会成功。因为我觉得这个是没有太大必要的,感兴趣的朋友可以把它改下。

在C#中实现简单的对象池的更多相关文章

  1. Java网络与多线程系列之1:实现一个简单的对象池

    前言 为什么要从对象池开始呢,先从一个网络IO操作的demo说起 比如下面这段代码,显而易见已经在代码中使用了一个固定大小的线程池,所以现在的重点在实现Runnble接口的匿名对象上,这个对象每次创建 ...

  2. Unity实现简单的对象池

    一.简介 先说说为什么要使用对象池 在Unity游戏运行时,经常需要生成一些物体,例如子弹.敌人等.虽然Unity中有Instantiate()方法可以使用,但是在某些情况下并不高效.特别是对于那些需 ...

  3. 状态机模式中的Task与对象池

    Task 抽象带来Task 首先,假设我们有这么一段逻辑:收到一个参数,先校验格式是否正确,再提取相关的参数出来,执行我们的事务,然后构建结果并返回.伪代码如下: /** * 一个engine类 ** ...

  4. Unity3D|-使用ScriptableObject脚本化对象来制作一个简单的对象池

    ScriptableObject是一个用于生成单独Asset的结构.同时,它也能被称为是Unity中用于处理序列化的结构. 可以作为我们存储资源数据的有效方案.同时此资源可以作为我们AB包的有效资源! ...

  5. 【JVM】Java 8 中的常量池、字符串池、包装类对象池

    1 - 引言 2 - 常量池 2.1 你真的懂 Java的“字面量”和“常量”吗? 2.2 常量和静态/运行时常量池有什么关系?什么是常量池? 2.3 字节码下的常量池以及常量池的加载机制 2.4 是 ...

  6. Java 中的对象池实现

    点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. 最近在 ...

  7. common-pool2对象池(连接池)的介绍及使用

    我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...

  8. 【h5-egret】深入浅出对象池

    最近看到对象池这一块的东西,是频繁创建和删除类型游戏优化性能的一个解决方案. 简单来讲对象池就是个数组,把不用的对象放进去,因为数组还保存了对象的引用,所以对象不会被回收,等需要用的时候再从数组中取出 ...

  9. 用Java实现一个通用并发对象池

    这篇文章里我们主要讨论下如何在Java里实现一个对象池.最近几年,Java虚拟机的性能在各方面都得到了极大的提升,因此对大多数对象而言,已经没有必要通过对象池来提高性能了.根本的原因是,创建一个新的对 ...

随机推荐

  1. NodeJs03 express框架 Todo商城

    前言 由于NodeJs本身的异步非阻塞特性和对http的天然支持,所以使用NodeJs编写高性能,可伸缩的Web服务器非常简单.开发完整的Web服务器还需要路由,错误处理,请求拦截,请求和响应的解析, ...

  2. 《大道至简》第一章 编程的精义 java伪代码形式

    愚公.这位名家身上,浓缩了项目组织者.团队经理.编程人员.技术分析师等众多角色的优秀素质. 愚公移山事件分析: 原始需求:惩山北之塞,出入之迂 项目沟通方式:聚室而某曰 项目目标:毕力平险,指通豫南, ...

  3. 静态编译zsummerX

    下载 https://github.com/zsummer/zsummerX 下载 http://ftp.gnu.org/gnu/glibc/ ../configure --prefix=/home/ ...

  4. 【C++ 拾遗】C++'s most vexing parse

    C++'s most vexing parse 是 Scott Meyers 在其名著<Effective STL>中创造的一个术语. Scott 用这个术语来形容 C++ 标准对于 de ...

  5. <转自原博客> 可爱的字符串算法们

    在非常强又非常关心学弟学妹学习的企鹅学长变态的考纲下,我们无奈中选择一起学习新姿势 first:KMP算法 这是一个小迪更过博客的算法,我就不好意思在这里献丑了,所以献上友链一份:http://rab ...

  6. python通过SSH登陆linux并操作

    使用python通过SSH登陆linux并操作 用的昨天刚接触到的库,在windows下通过paramiko来登录linux系统并执行了几个命令,基本算是初试成功,后面会接着学习的. 代码: > ...

  7. 【查看linux配置】查看linux系统常用的命令,Linux查看系统配置常用命令

    一.linux CPU大小  cat /proc/cpuinfo |grep "model name" && cat /proc/cpuinfo |grep &qu ...

  8. 开源免费的C/C++网络库(c/c++ sockets library)(转)

    原文转自 http://blog.csdn.net/weiwangchao_/article/details/8730199 (1)ACE 庞大.复杂,适合大型项目.开源.免费,不依赖第三方库,支持跨 ...

  9. OpenGL函数思考-glColor

    http://blog.csdn.net/shuaihj/article/details/7231980 OpenGL函数思考-glColor 函数原型:      glColor3b,glColor ...

  10. Cocos2D研究院之CCNode详解(三)

    http://www.xuanyusong.com/archives/950 上一章我们了解了cocos2d的项目路径以及工作原理,这次作者要真刀真枪地讲解代码了,咱们先来看看cocos2d最常用.也 ...