在C#中实现简单的对象池
当我们频繁创建删除大量对象的时候,对象的创建删除所造成的开销就不容小觑了。为了提高性能,我们往往需要实现一个对象池作为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#中实现简单的对象池的更多相关文章
- Java网络与多线程系列之1:实现一个简单的对象池
前言 为什么要从对象池开始呢,先从一个网络IO操作的demo说起 比如下面这段代码,显而易见已经在代码中使用了一个固定大小的线程池,所以现在的重点在实现Runnble接口的匿名对象上,这个对象每次创建 ...
- Unity实现简单的对象池
一.简介 先说说为什么要使用对象池 在Unity游戏运行时,经常需要生成一些物体,例如子弹.敌人等.虽然Unity中有Instantiate()方法可以使用,但是在某些情况下并不高效.特别是对于那些需 ...
- 状态机模式中的Task与对象池
Task 抽象带来Task 首先,假设我们有这么一段逻辑:收到一个参数,先校验格式是否正确,再提取相关的参数出来,执行我们的事务,然后构建结果并返回.伪代码如下: /** * 一个engine类 ** ...
- Unity3D|-使用ScriptableObject脚本化对象来制作一个简单的对象池
ScriptableObject是一个用于生成单独Asset的结构.同时,它也能被称为是Unity中用于处理序列化的结构. 可以作为我们存储资源数据的有效方案.同时此资源可以作为我们AB包的有效资源! ...
- 【JVM】Java 8 中的常量池、字符串池、包装类对象池
1 - 引言 2 - 常量池 2.1 你真的懂 Java的“字面量”和“常量”吗? 2.2 常量和静态/运行时常量池有什么关系?什么是常量池? 2.3 字节码下的常量池以及常量池的加载机制 2.4 是 ...
- Java 中的对象池实现
点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. 最近在 ...
- common-pool2对象池(连接池)的介绍及使用
我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...
- 【h5-egret】深入浅出对象池
最近看到对象池这一块的东西,是频繁创建和删除类型游戏优化性能的一个解决方案. 简单来讲对象池就是个数组,把不用的对象放进去,因为数组还保存了对象的引用,所以对象不会被回收,等需要用的时候再从数组中取出 ...
- 用Java实现一个通用并发对象池
这篇文章里我们主要讨论下如何在Java里实现一个对象池.最近几年,Java虚拟机的性能在各方面都得到了极大的提升,因此对大多数对象而言,已经没有必要通过对象池来提高性能了.根本的原因是,创建一个新的对 ...
随机推荐
- Oracle常用数据库系统表单以及SQL的整理
因为最近涉及到了一些数据库的归档,备份等工作,所以一部分的重心放在了数据库上,毕竟之前对数据库的了解也只停留在了一般的建表,查询,最多最多再写一写触发器之类的东西. 通常都是自己瞎搞搞,也就懂一点皮毛 ...
- C#中的&运算
2是一个比较特殊的数. 2的1次方2 2的2次方4 2的3次方8 2的4次方16 2的5次方32 2的6次方64 2的7次方128 2的8次方256 2的9次方512 2的10次方1024 2的11次 ...
- Java 中xml解析
1.String 字符串保持到txt文件 String xml ="abcdefghijk"; FileWriter fw = null; File f = new File(&q ...
- Codeforces Round #386 (Div. 2) 746F(set的运用)
题目大意 给出一个歌单(有n首歌),每个歌都有愉悦值和时间,你可以选择从第x首歌开始听(也就是选择连续的一段),并且你可以选择w首歌让它的时间减半,限制时间为k,求最大的愉悦值 首先我们需要贪心一下, ...
- 省选算法学习-回文自动机 && 回文树
前置知识 首先你得会manacher,并理解manacher为什么是对的(不用理解为什么它是$O(n)$,这个大概记住就好了,不过理解了更方便做$PAM$的题) 什么是回文自动机? 回文自动机(Pal ...
- rem布局和hotcss原理分析
rem布局的开源方案hotcss, 其原理个人理解如下: 手机px = (手机页面宽度/设计稿宽度) * 设计稿px 手机rem = 手机px / fontSize = (手机页面宽度/设计稿宽度) ...
- phantomjs和selenium模拟登陆qq空间
# -*- coding: utf-8 -*- from selenium import webdriver import time driver =webdriver.PhantomJS() dri ...
- code forces 994C
C. Two Squares time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- Java并发(3)- 聊聊Volatile
引言 谈到volatile关键字,大多数开发者都有一定了解,可以说是开发者非常熟悉,深入之后又非常陌生的一个关键字.相当于轻量的synchronized,也叫轻量级锁,与synchronized相比性 ...
- Vitamio介绍及使用
一.Vitamio介绍 1.1 Vitamio是什么? Vitamio是Android平台视音频播放组件,支持播放几乎格式的视频以及主流网络视频流(http/rtsp/mms等),详细的中文介绍: 这 ...