举例讲解Java设计模式中的对象池模式编程

定义
一个对象池是一组已经初始化过且可以使用的对象的集合,池的用户可以从池子中取得对象,对其进行操作处理,并在不需要时归还给池子而非销毁它。

若初始化、实例化的代价高,且有需求需要经常实例化,但每次实例化的数量较少的情况下,使用对象池可以获得显著的效能提升。从池子中取得对象的时间是可预测的,但新建一个实例所需的时间是不确定。

实现

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. 定时清理过期的对象。

(0)

相关推荐

  • 举例解析Java的设计模式编程中里氏替换原则的意义

    里氏替换原则,OCP作为OO的高层原则,主张使用"抽象(Abstraction)"和"多态(Polymorphism)"将设计中的静态结构改为动态结构,维持设计的封闭性."抽象"是语言提供的功能."多态"由继承语义实现. 里氏替换原则包含以下4层含义: 子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法. 子类中可以增加自己特有的方法. 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更

  • 解析Java编程中设计模式的开闭原则的运用

    开闭原则(Open Closed Principle)是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的.灵活的系统. 定义: 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. Softeware entities like classes,modules and functions should be open for extension but closed for modifications. 开闭原则的含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有代码

  • Java设计模式编程中的工厂方法模式和抽象工厂模式

    工厂方法模式 动机 创建一个对象往往需要复杂的过程,所以不适合包含在一个复合工厂中,当有新的产品时,需要修改这个复合的工厂,不利于扩展. 而且,有些对象的创建可以需要用到复合工厂访问不到的信息,所以,定义一个工厂接口,通过实现这个接口来决定实例化那个产品,这就是工厂方法模式,让类的实例化推迟到子类中进行. 目的 1. 定义一个接口,让子类决定实例化哪个产品. 2. 通过通用接口创建对象. 实现 1. 产品接口和具体产品很好理解. 2. 工厂类提供一个工厂方法,返回一个产品对象.但是这个工厂方法是

  • Java结构型设计模式中的适配器模式与桥接模式解析

    适配器模式 定义 适配器模式(英语:adapter pattern)有时候也称包装样式或者包装.将一个类的接口转接成用户所期待的.一个适配使得因接口不兼容而不能在一起工作的类工作在一起. 有两类适配器模式: 1. 对象适配器模式 - 对象适配器通过关联满足用户期待接口,还降低了代码间的不良耦合.在工作中推荐使用"对象适配". 2. 类适配器模式 - 这种适配器模式下,适配器继承自已实现的类(一般多重继承),java中没有多重继承,所以这里不做介绍. 实现 1. Target - 定义C

  • 实例讲解Java设计模式编程中的OCP开闭原则

    定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 问题由来:在软件的生命周期内,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试. 解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化.          开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统.开闭原则可能是设计模式六项原则中定义最模糊的一个了,它

  • 浅析Java设计模式编程中的单例模式和简单工厂模式

    单例模式 动机 有时候只有一个类的实例是很重要的.比如,一个系统应该只有一个窗口管理实例. 单例模式是最简单设计模式:类负责实例化自己,确保只有一个实例,并且提供一个访问这个实例的入口. 目的 1. 确保只有一个实例被创建. 2. 提供访问这个实例的入口. 使用final确保被创建一次,private的构造函数确保不被实例化.public的getInstance方法确保外部能够访问.下面是饿汉模式: public class Singleton { private static final Si

  • Java设计模式之装饰者模式详解和代码实例

    装饰者模式可以给已经存在的对象动态的添加能力.下面,我将会用一个简单的例子来演示一下如何在程序当中使用装饰者模式. 1.装饰者模式 让我们来假设一下,你正在寻找一个女朋友.有很多来自不同国家的女孩,比如:美国,中国,日本,法国等等,他们每个人都有不一样的个性和兴趣爱好,如果需要在程序当中模拟这么一种情况的话,假设每一个女孩就是一个Java类的话,那么就会有成千上万的类,这样子就会造成类的膨胀,而且这样的设计的可扩展性会比较差.因为如果我们需要一个新的女孩,就需要创建一个新的Java类,这实际上也

  • 详解Java设计模式编程中的依赖倒置原则

    定义: 高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类A一般是高层模块,负责复杂的业务逻辑:类B和类C是低层模块,负责基本的原子操作:假如修改类A,会给程序带来不必要的风险. 解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率.          依赖倒置原则基于这样一个事实:

  • 详解Java设计模式编程中的里氏替换原则

    定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型. 定义2:所有引用基类的地方必须能透明地使用其子类的对象. 问题由来:有一功能P1,由类A完成.现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成.新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障. 解决方

  • 讲解Java设计模式编程中的建造者模式与原型模式

    建造者模式 定义 又叫生成器模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象. 当创建复杂对象的算法应该独立于该对象的组成部分时,而且构造过程必须允许被构造的对象有不同的表示时.我们可以考虑使用建造者模式. 实现 1. Builder为创建一个Product对象的各个部件指定抽象接口.通常包含创建产品和返回产品的抽象方法,也可以是具体方法,把创建过程放到ConcreteBuilder类中. 2. ConcreteBuilder 实

随机推荐