基于LRU算法的Java对象池设计
刘伟军
(赣南师范学院物理与电子信息学院,江西赣州Mlooo)
对象池是管理与共享系统资源的一种缓存机制,亦称资源池⋯.使用对象池可以获得两大好处:一是可
以降低资源创建与撤销的成本,从而提高系统整体性能;二是有效控制系统资源的使用总量,避免系统因资
源耗尽而崩溃,从而提高系统的可伸缩性.对象池应用很广,例如,管理数据库连接对象池称为数据库连接
池 ;管理组件实例的对象池称为实例池,诸如EJB容器、COM +容器等.而weh服务器则利用H’兀.P连接
池增强对客户访问的处理效率.
1 设计原理
对象池技术就是在当对象第1次被访问后,将其保存在对象池中,第2次读取时,就直接从池中读取.对
象的持久状态存放在关系数据库中或其它介质上.
1.1 对象池命中率命中率是指从缓存中得到请求对象的百分比,它是考察对象池优劣的关键参数.
1.2 对象生命周期对象的生命周期结束时,它必须被替换出对象池.因此,对象何时该消亡,以什么样的
策略被更新,也是对象池必须要解决的问题1.3 对象的一致性对象池内的对象是原对象的副本,设计对象池时必须考虑如何保证对象池内的对象与
原对象的一致性,当对象池内的对象发生变化时,应及时更新对象在数据库中的持久状态.
2 基于LRU算法的对象池框架的实现
对象池框架主要类图如图1所示,这里假设对象池中存放的是银行帐户对象Account,其对象持久状态
在框架图l中PoolLru继承AbstractPool类,是采用LRU算法的对象池.当客户程序请求访问的帐户对
象不在池内时,AbstractPool会请求PooledObjectFactory,要求得到一个新的帐户对象,而AccountPooledObject—
Factory是具体的实现类,用于产出新的帐户对象.
为实现图l框架,需要解决对象替换策略,对象池大小,对象一致性,以及对象池命中率等问题.
2.1 基于LRU算法的对象替换策略
对象替换,指当对象池内的对象数量已经达到上限,但有新的对象要加入时,需按照某种算法从对象池
选择一个删除,以便添加新的对象.在对象池类PoolLRU中定义基于LRU算法的替换策略程序如下:
- public boolean addAccount(Account account){
- boolean flag false;
- double maxUseTime=0;
- double timeDur;//
- int curlndex=0;
- Account tempAccount=null;
- if(currentObjects<maxObjects){
- accountPool
- 一
- . add(account);
- currentObjects++;
- flag true:
- }else{
- for(int i-O;i<accountPool_.size();i++){
- tempAccount=(Account)accountPool一.elementAt(i);
- timeDur:System.currentTimeMillis()一tempAccount.retumLastUsage();
- if(timeDur>maxUseTime){
- maxUseTime=timeDur;
- curIndex=i;
- }
- accountPool一
- . remove(curlndex);
- accountPool一
- . add(account);
- flag true;
- }
- }
- return nag;
- }
2.2 命中率设计
对象池的命中率用来判断对象池设计的优劣.在对象池类PoolLRU中定义private int hits=0,private int
misses=O;每发生对象池命中时,hits++,而当访问对象不在对象池中时,就从关系数据库中读取,misses+
+,这两个变量用于评价对象池的效率.
2.3 基于LRU算法的对象池类实现
图l所示的PoolLRU类是对象池类,它继承AbstractPool类,实现了acquire()和release()两个方法.定
义了Vector容器变量存储被池化的对象.当需要创建新的帐户对象时,AbstractPool依靠AccountPooledOb.
jectFactory创建帐户对象.该类的具体定义如下:
- public class PoolLRU extends AbstractPool{
- String accountid;
- long ctime;
- String name=null;
- double balance=0;
- //对象池大小
- private int maxObjects;
- private Jut currentObjects;
- //定义对象池
- protected Vector accountPool一 ;
- private static DbCorm ectionPool dbConnPool:
- private AccountObserver aecountObserver;
- private int hits=0;
- private int misses=0:
- public PoolLRU(){
- accountPool一 =new Vector();
- dbConnPool=DbConnectionPoo1.getlnstance();
- maxObjects=8000;
- currentObjects=0:
- accountObserver=new AccountObserver();
- }
- public Resource acquire(String
- Account account=null;
- id){
- account getAccountByld(id);
- if(account! :nul1)hits++;
- if(account== nul1)l
- try{
- Connection conn=dbCormPoo1.acquire();
- Statement stmt=conn.createStatement();
- ResuhSet rs=strut.executeQuery(”Select id,name,balance FROM Accounts’’);
- while(IX3.next()){
- accounfid=1"5.getString(”id”);
- if(accountid.equals(id)){
- name=rs.getString(”nanle”);
- balance=rs.getDouble(”balance”);
- ctime=System.currentTimeMillis();
- account=new Account(aecounrid,llanle,balance,crime);
- misses+ + ;
- break;
- }
- }catch
- }catch
- }
- rs.close();
- stint.close();
- dbConnPoo1.retumConnection(corm);
- (SQLException e)}
- e.printStackTrace();
- return null;
- (Exception e){
- e.printStackTrace();
- retum null;
- }
- }
- return account;
- }
- public void release(Acount acount)
- retumAccount(account);
- }
- public void retumAccount(Account account){
- addAccount(account);
- accountObserver.update(this,account);
- }
- }
2.4 对象的一致性设计
对象池中对象是原对象的映射,系统实现必须保证对象池中对象和关系数据库中对象状态一致,当池内
对象状态发生变化时,处于关系数据库中对象的持久状态也应当立即更新.观察者模式是一种非常好的设计
模式,当池内中的一个对象状态发生变化,所有依赖于它的对象都得到通知并被更新,实现对象间的低耦合.
在图l所示的框架中,Observer接口表示“观察者”的接口,AccountObserver实现该接口,当帐户对象被归还
对象池内时,“观察者”会被通知,“观察者”将调用Update()方法将对象状态写人数据库中以保持和数据库
同步.
3 结束语
对象池技术是提高服务端性能的有效技术,能够减少对象创建次数,节省对象访问时间,同时可以控制
服务端内存资源,避免内存耗尽.本文在J2EE平台上实现了一个基于LRU算法的对象池框架.进一步的研
究内容主要包括:(1)研究在不同对象池大小情况下,LRU对象池性能;(2)在对象池内尝试其它经典算法,
比较各种算法的性能;(3)研究新的算法,提高对象池的命中率.
(文章来源:www.nba114.com 转载请注明)