java设计模式之实现对象池模式示例分享

 更新时间:2014年02月18日 11:08:38   作者:  
对象池模式经常用在频繁创建、销毁对象(并且对象创建、销毁开销很大)的场景,比如数据库连接池、线程池、任务队列池等。本代码简单,没有限制对象池大小

ObjectPool抽象父类

复制代码 代码如下:

import java.util.Iterator;
import java.util.Vector;

public abstract class ObjectPool<T> {

   private Vector<T> locked, unlocked;   // locked是已占用的对象集合,unlocked是可用对象集合

   public ObjectPool() {
    locked = new Vector<T>();
    unlocked = new Vector<T>();
   }

   // 创建对象
   protected abstract T create();

   // 验证对象有效性
   public abstract boolean validate(T o);

   // 使对象失效
   public abstract void expire(T o);

   // 检出:从对象池获取对象
   public synchronized T checkOut() {
    T t;
    if (unlocked.size() > 0) {
     Iterator<T> iter = unlocked.iterator();
     while(iter.hasNext()) {
      t = iter.next();
      if(validate(t)) {   // 对象有效
       unlocked.remove(t);
       locked.add(t);

       return t;
      }
      else {   // 对象已经失效
       unlocked.remove(t);
       expire(t);
      }
     }
    }

    // 对象池塘没有可用对象,创建新对象
    t = create();
    locked.add(t);

    return (t);
   }

   // 检入:释放对象回对象池
   public synchronized void checkIn(T t) {
    locked.remove(t);
    if(validate(t)) {   // 如果对象仍有效则放回可用对象集合中
     unlocked.add(t);
    }
    else {   // 否则使对象失效
     expire(t);
    }
   }

}

JDBCConnectionPool子类

复制代码 代码如下:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JDBCConnectionPool extends ObjectPool<Connection> {

 private String url, usr, pwd;

 public JDBCConnectionPool(String driver, String url, String usr, String pwd) {
  super();

  // 加载对应的数据库驱动
  try {
   Class.forName(driver).newInstance();
  }
  catch(Exception e) {
   e.printStackTrace();
  }

  this.url = url;
  this.usr = usr;
  this.pwd = pwd;
 }

 @Override
 protected Connection create() {
  try {
   return DriverManager.getConnection(url, usr, pwd);
  }
  catch(SQLException e) {
   e.printStackTrace();
  }

  return null;
 }

 @Override
 public boolean validate(Connection o) {
  try {
   return o.isClosed();
  }
  catch(SQLException e) {
   e.printStackTrace();
  }

  return false;
 }

 @Override
 public void expire(Connection o) {
  try {
   o.close();
  }
  catch(SQLException e) {
   e.printStackTrace();
  }
  finally {
   o = null;
  }
 }

 public static void main(String[] args) {
  JDBCConnectionPool dbConnPool = new JDBCConnectionPool("com.mysql.jdbc.Driver", "jdbc:mysql://127.0.0.1:3306/test", "root", "123");

  // 获取数据库连接对象
  Connection conn = dbConnPool.checkOut();

  // 使用数据库连接对象
  // ...

  // 释放数据库连接对象
  dbConnPool.checkIn(conn);

 }

}

复制代码 代码如下:

class Pool {
   private static final MAX_AVAILABLE = 100;
   private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

   public Object getItem() throws InterruptedException {
     available.acquire();
     return getNextAvailableItem();
   }

   public void putItem(Object x) {
     if (markAsUnused(x))
       available.release();
   }

   // Not a particularly efficient data structure; just for demo

   protected Object[] items = ... whatever kinds of items being managed
   protected boolean[] used = new boolean[MAX_AVAILABLE];

   protected synchronized Object getNextAvailableItem() {
     for (int i = 0; i < MAX_AVAILABLE; ++i) {
       if (!used[i]) {
          used[i] = true;
          return items[i];
       }
     }
     return null; // not reached
   }

   protected synchronized boolean markAsUnused(Object item) {
     for (int i = 0; i < MAX_AVAILABLE; ++i) {
       if (item == items[i]) {
          if (used[i]) {
            used[i] = false;
            return true;
          } else
            return false;
       }
     }
     return false;
   }

 }

相关文章

  • 详解java封装实现Excel建表读写操作

    详解java封装实现Excel建表读写操作

    这篇文章给大家分享了java封装实现Excel建表读写操作的相关知识点内容,有需要的朋友们可以学习下。
    2018-08-08
  • Java简单几步实现一个二叉搜索树

    Java简单几步实现一个二叉搜索树

    二叉树包含了根节点,孩子节点,叶节点,每一个二叉树只有一个根节点,每一个结点最多只有两个节点,左子树的键值小于根的键值,右子树的键值大于根的键值,下面这篇文章主要给大家介绍了关于如何在Java中实现二叉搜索树的相关资料,需要的朋友可以参考下
    2023-02-02
  • 如何解决springboot启动的时候required a bean of type 'XXX' not be问题

    如何解决springboot启动的时候required a bean of ty

    Spring Boot启动失败,提示缺少`UserDao`类型的Bean,解决方案一:为`UserDao`接口添加`@Mapper`注解,重新启动;解决方案二:使用`@MapperScan`注解扫描Mapper接口所在的包
    2024-12-12
  • java和javascript中过滤掉img形式的字符串不显示图片的方法

    java和javascript中过滤掉img形式的字符串不显示图片的方法

    这篇文章主要介绍了java和javascript中过滤掉img形式的字符串不显示图片的方法,以实例形式分别讲述了采用java和javascript实现过滤掉img形式字符串的技巧,需要的朋友可以参考下
    2015-02-02
  • 解决spring @ControllerAdvice处理异常无法正确匹配自定义异常

    解决spring @ControllerAdvice处理异常无法正确匹配自定义异常

    这篇文章主要介绍了解决spring @ControllerAdvice处理异常无法正确匹配自定义异常的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 如何在spring事务提交之后进行异步操作

    如何在spring事务提交之后进行异步操作

    这篇文章主要为大家介绍了如何在spring事务提交之后进行异步操作,这些异步操作必须得在该事务成功提交后才执行,回滚则不执行,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2023-09-09
  • Java数据结构之二叉排序树的实现

    Java数据结构之二叉排序树的实现

    二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。本文详细介绍了二叉排序树的原理,并且提供了Java代码的完全实现。需要的可以参考一下
    2022-01-01
  • SpringBoot自定义注解API数据加密和签名校验

    SpringBoot自定义注解API数据加密和签名校验

    这篇文章主要介绍了SpringBoot自定义注解API数据加密和签名校验,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 详解Spark Sql在UDF中如何引用外部数据

    详解Spark Sql在UDF中如何引用外部数据

    这篇文章主要为大家介绍了详解Spark Sql在UDF中如何引用外部数据示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • JAVA下单接口优化实战TPS性能提高10倍

    JAVA下单接口优化实战TPS性能提高10倍

    今天小编就为大家分享一篇关于JAVA下单接口优化实战TPS性能提高10倍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论