举例讲解Java设计模式中的对象池模式编程
程序员文章站
2024-03-08 14:36:28
定义
一个对象池是一组已经初始化过且可以使用的对象的集合,池的用户可以从池子中取得对象,对其进行操作处理,并在不需要时归还给池子而非销毁它。
若初始化、实例化的代价高,...
定义
一个对象池是一组已经初始化过且可以使用的对象的集合,池的用户可以从池子中取得对象,对其进行操作处理,并在不需要时归还给池子而非销毁它。
若初始化、实例化的代价高,且有需求需要经常实例化,但每次实例化的数量较少的情况下,使用对象池可以获得显著的效能提升。从池子中取得对象的时间是可预测的,但新建一个实例所需的时间是不确定。
实现
1. reusable - 对象池中的对象,通常实例化代价比较高。
2. client - 使用一个对象的实例。
3. reusablepool - 管理对象的实例化,回收和销毁。
单个实例中主要的思想
1.一个栈,这里用stack
2.初始化方法,容器开启的时候可以预先创建池
3.创建实例的方法
4.提供从池中获得对象实例的方法
5.提供返回的方法,不返回后果很严重
6.控制请求等待时间的方法,过了一定的事件还没获得对象实例,就返回一个null指针
import java.util.stack; @suppresswarnings("unchecked") public class objectpool { public objectpool() { } private poolparam poolparam; public void setpoolparam(poolparam poolparam) { this.poolparam = poolparam; } // 当前总对象个数 private int currentnum = 0; private class clazz; public void setclazz(class clazz) { this.clazz = clazz; } // 栈,用来存放对象,模拟一个池 private stack stack; public stack getstack() { return stack; } public void setstack(stack stack) { this.stack = stack; } // ................................................................. // 等待超时的记数变量 private int timewait = 0; // ................................................................. // 创建对象池 public void initalpool(poolparam poolparam, class clazz) { this.setpoolparam(poolparam); this.setclazz(clazz); stack = new stack(); stack.clear(); // system.out.println("obj..pool is initial..."); // 生成配置最小对象数,并压入栈中 try { for (int i = 0; i < poolparam.getminobjectcount(); i++) { // 根据poolparam初始化对象池 stack.push(clazz.newinstance()); } } catch (instantiationexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } } // 创建单个对象 private object createobj(class clazz) { object obj = null; try { obj = clazz.newinstance(); // system.out.println("a new one..."); } catch (instantiationexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } return obj; } // 对象池提供的get方法 public object getinstance(){ // system.out.println(stack.size()); object object = null; if (stack.size() == 0) { // 如果当前栈的长度为0,并且总的对象数没有超过定义最大数 if ((currentnum + poolparam.getminobjectcount()) < poolparam .getmaxobjectcount()) { // 新创建一个对象 object = this.createobj(clazz); // 对象数+1 currentnum++; } else { synchronized (this) { try { waitme(this); } catch (exception e) { e.printstacktrace(); } // 获得通知后检测栈中是为空,并给出刚刚释放的资源 if (!stack.empty()) { object = stack.pop(); } } } } else if (stack.size() > 0) { object = stack.pop(); // system.out.println(stack.size()); } return object; } // 返回对象的方法 public void returnobj(object obj) { if (clazz.isinstance(obj)) { stack.push(obj); synchronized (this) { notify(); } } else { system.out.println("this object can not push to stack!"); } } // 等待递归算法 private void waitme(objectpool pool) { // 等待2s的技术控制 if (timewait >= 2000) { system.out.println("jump up this step.."); timewait = 0; return; } else { try { pool.wait(500); // 等待计数累加。。 timewait +=1000; system.out.println("waiting time to free obj.."); if (stack.empty()) { system.out.println("agian...."); waitme(pool); } } catch (interruptedexception e) { e.printstacktrace(); } } } }
管理池类,这个不是很难,同步了就好
@suppresswarnings("unchecked") public class objectpoolmanage { private objectpoolmanage() { } private static objectpool pool; // 实现一个单例的获取方法....默认 public static synchronized objectpool getcacheobject(class clazz) { if (null != pool) { return pool; } else { createobjectpool(null, clazz); return pool; } } // 实现一个单例的获取方法...自定义 public static synchronized objectpool getcacheobject(poolparam p, class clazz) { if (null != pool) { return pool; } else { createobjectpool(p, clazz); return pool; } } private static objectpool createobjectpool(poolparam p, class clazz) { pool = new objectpool(); if (null == p) { pool.initalpool(new poolparam(5,10), clazz); } else { pool.initalpool(p, clazz); } return pool; } private static class getclazz(){ class clazz=null; try { clazz= class.forname(ppp.getpropertybyname("objectpath")); } catch (classnotfoundexception e) { e.printstacktrace(); } return clazz; } }
相关问题和实现
1. 对象池中可以限制对象的个数,当超过限制时,对象池需要返回异常或者空值,以通知客户。
2. 在多线程环境中,在checkout和checkin方法需要同步。
3. 定时清理过期的对象。