对象池技术的原理及其实现

上传人:l****6 文档编号:38057301 上传时间:2018-04-26 格式:DOC 页数:6 大小:35KB
返回 下载 相关 举报
对象池技术的原理及其实现_第1页
第1页 / 共6页
对象池技术的原理及其实现_第2页
第2页 / 共6页
对象池技术的原理及其实现_第3页
第3页 / 共6页
对象池技术的原理及其实现_第4页
第4页 / 共6页
对象池技术的原理及其实现_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《对象池技术的原理及其实现》由会员分享,可在线阅读,更多相关《对象池技术的原理及其实现(6页珍藏版)》请在金锄头文库上搜索。

1、1对象池技术的原理及其实现摘 要 本文在分析对象池技术基本原理的基础上,给出了对象池技术的两种实现方式。还指出了使用对象池技术时所应注意的问题。关键词 对象池;对象池技术;Java 对象;性能 1 Java 对象的生命周期分析Java 对象的生命周期大致包括三个阶段:对象的创建,对象的使用,对象的清除。因此,对象的生命周期长度可用如下的表达式表示:T = T1 + T2 +T3。其中 T1 表示对象的创建时间,T2 表示对象的使用时间,而 T3 则表示其清除时间。由此,我们可以看出,只有 T2 是真正有效的时间,而 T1、T3 则是对象本身的开销。下面再看看 T1、T3 在对象的整个生命周期中

2、所占的比例。我们知道,Java 对象是通过构造函数来创建的,在这一过程中,该构造函数链中的所有构造函数也都会被自动调用。另外,默认情况下,调用类的构造函数时,Java 会把变量初始化成确定的值:所有的对象被设置成 null,整数变量(byte、short、int、long)设置成 0,float 和 double 变量设置成 0.0,逻辑值设置成false。所以用 new 关键字来新建一个对象的时间开销是很大的,如表 1 所示。表 1 一些操作所耗费时间的对照表运算操作示例标准化时间2本地赋值i = n1.0实例赋值this.i = n1.2方法调用Funct()5.9新建对象New Obje

3、ct()980新建数组New int103100从表 1 可以看出,新建一个对象需要 980 个单位的时间,是本地赋值时间的 980倍,是方法调用时间的 166 倍,而若新建一个数组所花费的时间就更多了。3再看清除对象的过程。我们知道,Java 语言的一个优势,就是 Java 程序员勿需再像 C/C+程序员那样,显式地释放对象,而由称为垃圾收集器(Garbage Collector)的自动内存管理系统,定时或在内存凸现出不足时,自动回收垃圾对象所占的内存。凡事有利总也有弊,这虽然为 Java 程序设计者提供了极大的方便,但同时它也带来了较大的性能开销。这种开销包括两方面,首先是对象管理开销,G

4、C 为了能够正确释放对象,它必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等。其次,在 GC 开始回收“垃圾”对象时,系统会暂停应用程序的执行,而独自占用 CPU。因此,如果要改善应用程序的性能,一方面应尽量减少创建新对象的次数;同时,还应尽量减少 T1、T3 的时间,而这些均可以通过对象池技术来实现。2 对象池技术的基本原理对象池技术基本原理的核心有两点:缓存和共享,即对于那些被频繁使用的对象,在使用完后,不立即将它们释放,而是将它们缓存起来,以供后续的应用程序重复使用,从而减少创建对象和释放对象的次数,进而改善应用程序的性能。事实上,由于对象池技术将对象限制在一定的数量,

5、也有效地减少了应用程序内存上的开销。实现一个对象池,一般会涉及到如下的类:1)对象池工厂(ObjectPoolFactory)类该类主要用于管理相同类型和设置的对象池(ObjectPool),它一般包含如下两个方法:createPool:用于创建特定类型和设置的对象池;destroyPool:用于释放指定的对象池;同时为保证 ObjectPoolFactory 的单一实例,可以采用 Singleton 设计模式,见下4述 getInstance 方法的实现:public static ObjectPoolFactory getInstance() if (poolFactory = null)

6、 poolFactory = new ObjectPoolFactory();return poolFactory; 2)参数对象(ParameterObject)类该类主要用于封装所创建对象池的一些属性参数,如池中可存放对象的数目的最大值(maxCount)、最小值(minCount)等。3)对象池(ObjectPool)类用于管理要被池化对象的借出和归还,并通知 PoolableObjectFactory 完成相应的工作。它一般包含如下两个方法:getObject:用于从池中借出对象;returnObject:将池化对象返回到池中,并通知所有处于等待状态的线程;4)池化对象工厂(Poola

7、bleObjectFactory)类该类主要负责管理池化对象的生命周期,就简单来说,一般包括对象的创建及销毁。该类同 ObjectPoolFactory 一样,也可将其实现为单实例。3 通用对象池的实现对象池的构造和管理可以按照多种方式实现。最灵活的方式是将池化对象的Class 类型在对象池之外指定,即在 ObjectPoolFactory 类创建对象池时,动态指定该对象池所池化对象的 Class 类型,其实现代码如下:. . . public ObjectPool createPool(ParameterObject paraObj,Class clsType) return new Obj

8、ectPool(paraObj, clsType); . . .其中,paraObj 参数用于指定对象池的特征属性,clsType 参数则指定了该对象池5所存放对象的类型。对象池(ObjectPool)创建以后,下面就是利用它来管理对象了,具体实现如下:public class ObjectPool private ParameterObject paraObj;/该对象池的属性参数对象private Class clsType;/该对象池中所存放对象的类型private int currentNum = 0; /该对象池当前已创建的对象数目private Object currentObj;

9、/该对象池当前可以借出的对象private Vector pool;/用于存放对象的池public ObjectPool(ParameterObject paraObj, Class clsType) this.paraObj = paraObj;this.clsType = clsType;pool = new Vector();public Object getObject() if (pool.size() = paraObj.getMinCount() if (currentNum = paraObj.getMaxCount() /如果当前池中无对象可用,而且已创建的对象数目小于所限制

10、的最大值,就利用/PoolObjectFactory 创建一个新的对象PoolableObjectFactory objFactory =PoolableObjectFactory.getInstance();currentObj = objFactory.create Object (clsType);currentNum+; else /如果当前池中无对象可用,而且所创建的对象数目已达到所限制的最大值,/就只能等待其它线程返回对象到池中synchronized (this) try wait(); catch (InterruptedException e) System.out.prin

11、tln(e.getMessage();e.printStackTrace();6currentObj = pool.firstElement(); else /如果当前池中有可用的对象,就直接从池中取出对象currentObj = pool.firstElement();return currentObj;public void returnObject(Object obj) /确保对象具有正确的类型if(obj.isInstance(clsType)pool.addElement(obj);synchronized (this) notifyAll();elsethrownewIllega

12、lArgumentException(“该对象池不能存放指定的对象类型“); 从上述代码可以看出,ObjectPool 利用一个 java.util.Vector 作为可扩展的对象池,并通过它的构造函数来指定池化对象的 Class 类型及对象池的一些属性。在有对象返回到对象池时,它将检查对象的类型是否正确。当对象池里不再有可用对象时,它或者等待已被使用的池化对象返回池中,或者创建一个新的对象实例。不过,新对象实例的创建并不在 ObjectPool 类中,而是由 PoolableObjectFactory 类的createObject 方法来完成的,具体实现如下:. . .public Obje

13、ct createObject(Class clsType) Object obj = null;try obj = clsType.newInstance(); catch (Exception e) e.printStackTrace(); 7return obj; . . .这样,通用对象池的实现就算完成了,下面再看看客户端(Client)如何来使用它,假定池化对象的 Class 类型为 StringBuffer:. . ./创建对象池工厂ObjectPoolFactory poolFactory = ObjectPoolFactory. getInstance ();/定义所创建对象池

14、的属性ParameterObject paraObj = new ParameterObject(2,1);/利用对象池工厂,创建一个存放 StringBuffer 类型对象的对象池ObjectPool pool = poolFactory.createPool(paraObj,String Buffer.class);/从池中取出一个 StringBuffer 对象StringBuffer buffer = (StringBuffer)pool.getObject();/使用从池中取出的 StringBuffer 对象buffer.append(“hello“);System.out.pri

15、ntln(buffer.toString(); . . .可以看出,通用对象池使用起来还是很方便的,不仅可以方便地避免频繁创建对象的开销,而且通用程度高。但遗憾的是,由于需要使用大量的类型定型(cast)操作,再加上一些对 Vector 类的同步操作,使得它在某些情况下对性能的改进非常有限,尤其对那些创建周期比较短的对象。4 专用对象池的实现由于通用对象池的管理开销比较大,某种程度上抵消了重用对象所带来的大部分优势。为解决该问题,可以采用专用对象池的方法。即对象池所池化对象的Class 类型不是动态指定的,而是预先就已指定。这样,它在实现上也会较通用对象池简单些,可以不要 ObjectPool

16、Factory 和 PoolableObjectFactory 类,而将它们的功能直接融合到 ObjectPool 类,具体如下(假定被池化对象的 Class 类型仍为8StringBuffer,而用省略号表示的地方,表示代码同通用对象池的实现):public class ObjectPool private ParameterObject paraObj;/该对象池的属性参数对象private int currentNum = 0; /该对象池当前已创建的对象数目private StringBuffer currentObj;/该对象池当前可以借出的对象private Vector pool;/用于存放对象的池public ObjectPool(ParameterObject paraObj) this.paraObj = paraObj;pool = new Vector();public StringBuffer getObj

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号