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

 更新时间:2016年02月02日 08:52:26   作者:lixiang0522  
这篇文章主要介绍了Java设计模式中的对象池模式编程示例分享,对象池模式经常在多线程开发时被用到,需要的朋友可以参考下

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

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

实现

20162284749593.gif (464×232)

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

相关文章

  • 利用JAVA反射,读取数据库表名,自动生成对应实体类的操作

    利用JAVA反射,读取数据库表名,自动生成对应实体类的操作

    这篇文章主要介绍了利用JAVA反射,读取数据库表名,自动生成对应实体类的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • SpringBoot项目热部署的实现

    SpringBoot项目热部署的实现

    SpringBoot项目热部署是一种让开发人员在修改代码后无需重启应用即可看到更改效果的技术,通过使用SpringBoot的DevTools等工具,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-09-09
  • java  HttpServletRequest和HttpServletResponse详解

    java HttpServletRequest和HttpServletResponse详解

    这篇文章主要介绍了java HttpServletRequest和HttpServletResponse详解的相关资料,需要的朋友可以参考下
    2016-12-12
  • MyBatis-Plus Generator配置详解

    MyBatis-Plus Generator配置详解

    这篇文章主要介绍了MyBatis-Plus Generator配置详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Springboot - Fat Jar示例详解

    Springboot - Fat Jar示例详解

    这篇文章主要介绍了Springboot - Fat Jar详解,Spring Boot内嵌容器,通过java -jar命令便可以直接启动应用,今天带着大家探索FAT JAR启动的背后原理,需要的朋友可以参考下
    2023-02-02
  • java线程中断 interrupt 和 LockSupport解析

    java线程中断 interrupt 和 LockSupport解析

    这篇文章主要为大家介绍了java线程中断 interrupt 和 LockSupport示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • javaweb中Http协议详解

    javaweb中Http协议详解

    HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程。这篇文章主要为大家详细介绍了javaweb中的Http协议,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • 基于Java Tomcat和激活MyEclips的深入理解

    基于Java Tomcat和激活MyEclips的深入理解

    本篇文章是对Java中的Tomcat和激活MyEclips进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • HDFS中JAVA API的使用

    HDFS中JAVA API的使用

    HDFS是一个分布式文件系统,既然是文件系统,就可以对其文件进行操作,比如说新建文件、删除文件、读取文件内容等操作。下面记录一下使用JAVA API对HDFS中的文件进行操作的过程
    2017-07-07
  • spring boot org.junit.jupiter.api不存在的解决

    spring boot org.junit.jupiter.api不存在的解决

    这篇文章主要介绍了spring boot org.junit.jupiter.api不存在的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论