Java对象池的简单实现

1. 对象池
当调用对象时,不使用常规的new 构造子的方式,而是通过一个对象池操作。
即如果池中存在该对象,则取出;如果不存在,则新建一个对象并存储在池中。当使用完该对象后,则将该对象的归还给对象池。
这里会存在几个问题,必须注意。
Tips 1,考虑多线程状态下的存取对象;
Tips 2,考虑将对象池目录表设计为Singleton模式,这样使得内存中仅存在唯一的一份缓存对象的表。

import java.util.ArrayList;
import java.util.List;
 
public class ObjectUnit<T> {
    private Class<T> type;
    private List<T> items = new ArrayList<T>();
    private List<Boolean> checkedOut = new ArrayList<Boolean>();
    private int semaphore;
 
    public ObjectUnit(Class<T> type) {
       this.type = type;
    }
 
    public synchronized T addItem() {
       T obj;
       try {
           obj = type.newInstance();
       } catch (Exception e) {
           throw new RuntimeException(e);
       }
       items.add(obj);
       checkedOut.add(false);
       return obj;
    }
 
    public synchronized T checkOut() {
       if (semaphore < items.size()) {
           semaphore++;
           return getItem();
       } else
           return addItem();
    }
 
    public synchronized void checkIn(T x) {
       if (releaseItem(x))
           semaphore--;
    }
 
    private synchronized T getItem() {
       for (int index = 0; index < checkedOut.size(); index++)
           if (!checkedOut.get(index)) {
              checkedOut.set(index, true);
              return items.get(index);
           }
       return null;
    }
 
    private synchronized boolean releaseItem(T item) {
       int index = items.indexOf(item);
       if (index == -1)
           return false; // Not in the list
       if (checkedOut.get(index)) {
           checkedOut.set(index, false);
           return true;
       }
       return false;
    }
}

对象池目录表设计
使用 Map<Class<?>, ObjectUnit<?>>来保存当前对象池中类型目录,并把它设计为线程安全的 ConcurrentHashMap
这里的getObj方法和renObj方法不用加锁,因为它调用的对象单元类是线程安全的,并且Map是线程安全的。
此外,这里在处理泛型的时候,会有warning产生,因为之前定义Map中使用<?>,而后面的两个泛型方法指定<T>。还没有想到更好的解决办法。

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
public class Provider {
    private Map<Class<?>, ObjectUnit<?>> providers = new ConcurrentHashMap<Class<?>, ObjectUnit<?>>();
    private static Provider instance = new Provider();
 
    private Provider() {
    }
 
    public static Provider getInstance() {
       return instance;
    }
 
    @SuppressWarnings("unchecked")
    public <T> T getObj(Class<T> key) {
       ObjectUnit value = providers.get(key);
        if (value != null) {
           return (T) value.checkOut();
       } else {
           value = new ObjectUnit<T>(key);
           providers.put(key, value);
           return (T) value.addItem();
       }
    }
 
    @SuppressWarnings("unchecked")
    public <T> void renObj(T x) {
       if (providers.containsKey(x.getClass())) {
           ObjectUnit value = providers.get(x.getClass());
           value.checkIn(x);
       }
    }
}

转载自:http://zhangjunhd.blog.51cto.com/113473/66059/


代码二:


public class ObjectPool {       
    private int numObjects = 10; // 对象池的大小       
    private int maxObjects = 50; // 对象池最大的大小       
    private Vector objects = null; //存放对象池中对象的向量( PooledObject类型)         
    
    public ObjectPool() {              
    }       
      
    /*** 创建一个对象池***/       
    public synchronized void createPool(){       
        // 确保对象池没有创建。如果创建了,保存对象的向量 objects 不会为空       
        if (objects != null) {       
            return; // 如果己经创建,则返回       
        }       
      
        // 创建保存对象的向量 , 初始时有 0 个元素       
        objects = new Vector();       
      
        // 根据 numObjects 中设置的值,循环创建指定数目的对象       
        for (int x = 0; x < numObjects; x++) {       
           if ((objects.size() == 0)&&this.objects.size() <this.maxObjects) {    
              Object obj = new Obj();       
              objects.addElement(new PooledObject(obj));                 
      }  
    }  
    }       
      
    public synchronized Object getObject(){       
        // 确保对象池己被创建       
        if (objects == null) {       
            return null; // 对象池还没创建,则返回 null       
        }       
      
        Object conn = getFreeObject(); // 获得一个可用的对象       
      
        // 如果目前没有可以使用的对象,即所有的对象都在使用中       
        while (conn == null) {       
            wait(250);       
            conn = getFreeObject(); // 重新再试,直到获得可用的对象,如果       
            // getFreeObject() 返回的为 null,则表明创建一批对象后也不可获得可用对象       
        }       
      
        return conn;// 返回获得的可用的对象       
    }       
      
    /**    
     * 本函数从对象池对象 objects 中返回一个可用的的对象,如果    
     * 当前没有可用的对象,则创建几个对象,并放入对象池中。    
     * 如果创建后,所有的对象都在使用中,则返回 null    
     */      
    private Object getFreeObject(){       
      
        // 从对象池中获得一个可用的对象       
        Object obj = findFreeObject();       
      
        if (obj == null) {       
            createObjects(incrementalObjects);     //如果目前对象池中没有可用的对象,创建一些对象       
  
            // 重新从池中查找是否有可用对象       
            obj = findFreeObject();       
                     
           // 如果创建对象后仍获得不到可用的对象,则返回 null       
            if (obj == null) {       
                return null;       
            }       
        }       
      
        return obj;       
    }       
      
    /**    
     * 查找对象池中所有的对象,查找一个可用的对象,    
     * 如果没有可用的对象,返回 null    
     */      
    private Object findFreeObject(){       
      
        Object obj = null;       
        PooledObject pObj = null;       
      
        // 获得对象池向量中所有的对象       
        Enumeration enumerate = objects.elements();       
      
        // 遍历所有的对象,看是否有可用的对象       
        while (enumerate.hasMoreElements()) {       
            pObj = (PooledObject) enumerate.nextElement();       
                      
           // 如果此对象不忙,则获得它的对象并把它设为忙       
            if (!pObj.isBusy()) {       
                obj = pObj.getObject();       
                pObj.setBusy(true);       
           }  
     
        return obj;// 返回找到到的可用对象       
    }       
      
      
    /**    
     * 此函数返回一个对象到对象池中,并把此对象置为空闲。    
     * 所有使用对象池获得的对象均应在不使用此对象时返回它。    
     */      
      
    public void returnObject(Object obj) {       
      
        // 确保对象池存在,如果对象没有创建(不存在),直接返回       
        if (objects == null) {       
            return;       
        }       
      
        PooledObject pObj = null;       
      
        Enumeration enumerate = objects.elements();       
      
        // 遍历对象池中的所有对象,找到这个要返回的对象对象       
        while (enumerate.hasMoreElements()) {       
            pObj = (PooledObject) enumerate.nextElement();       
  
            // 先找到对象池中的要返回的对象对象       
            if (obj == pObj.getObject()) {       
                // 找到了 , 设置此对象为空闲状态       
                pObj.setBusy(false);       
                break;       
            }       
        }       
    }       
      
      
    /**    
     * 关闭对象池中所有的对象,并清空对象池。    
     */      
    public synchronized void closeObjectPool() {       
      
        // 确保对象池存在,如果不存在,返回       
        if (objects == null) {       
            return;       
        }       
      
        PooledObject pObj = null;       
      
        Enumeration enumerate = objects.elements();       
      
        while (enumerate.hasMoreElements()) {       
      
            pObj = (PooledObject) enumerate.nextElement();       
      
            // 如果忙,等 5 秒       
            if (pObj.isBusy()) {       
                wait(5000); // 等 5 秒       
            }       
      
            // 从对象池向量中删除它       
            objects.removeElement(pObj);       
        }       
      
        // 置对象池为空       
        objects = null;       
    }       
      
      
    /**    
     * 使程序等待给定的毫秒数    
     */      
    private void wait(int mSeconds) {       
        try {       
            Thread.sleep(mSeconds);       
        }  
       catch (InterruptedException e) {       
        }       
    }       
      
     
    /**    
     * 内部使用的用于保存对象池中对象的类。    
     * 此类中有两个成员,一个是对象,另一个是指示此对象是否正在使用的标志 。 
     */      
    class PooledObject {       
      
        Object objection = null;// 对象       
        boolean busy = false; // 此对象是否正在使用的标志,默认没有正在使用       
      
        // 构造函数,根据一个 Object 构告一个 PooledObject 对象       
        public PooledObject(Object objection) {       
      
            this.objection = objection;       
      
        }       
      
        // 返回此对象中的对象       
        public Object getObject() {       
            return objection;       
        }       
      
        // 设置此对象的,对象       
        public void setObject(Object objection) {       
            this.objection = objection;       
      
        }       
      
        // 获得对象对象是否忙       
        public boolean isBusy() {       
            return busy;       
        }       
      
        // 设置对象的对象正在忙       
        public void setBusy(boolean busy) {       
            this.busy = busy;       
        }       
    }       
}      
   
   
测试类:  
代码如下:  
      
public class ObjectPoolTest {       
    public static void main(String[] args) throws Exception {       
        ObjectPool objPool = new ObjectPool();  
      
        objPool.createPool();       
        Object obj = objPool.getObject();       
        returnObject(obj);  
        objPool.closeObjectPool();       
    }       
}  

转自:http://blog.csdn.net/shimiso/article/details/9814917?utm_source=tuicool&utm_medium=referral

另外可参考:模拟数据库连接池  http://www.cnblogs.com/xinye/p/3907642.html



  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值