/**
  * 查找连接池中所有的连接,查找一个可用的数据库连接, 如果没有可用的连接,返回 null
  *
  * @return 返回一个可用的数据库连接
  */
  private Connection findFreeConnection() throws SQLException {
  Connection conn = null;
  PooledConnection pConn = null;
  // 获得连接池向量中所有的对象
  Enumeration enumerate = connections.elements();
  // 遍历所有的对象,看是否有可用的连接
  while (enumerate.hasMoreElements()) {
  pConn = (PooledConnection) enumerate.nextElement();
  if (!pConn.isBusy()) {
  // 如果此对象不忙,则获得它的数据库连接并把它设为忙
  conn = pConn.getConnection();
  pConn.setBusy(true);
  // 测试此连接是否可用
  if (!testConnection(conn)) {
  // 如果此连接不可再用了,则创建一个新的连接,
  // 并替换此不可用的连接对象,如果创建失败,返回 null
  try {
  conn = newConnection();
  } catch (SQLException e) {
  System.out.println(" 创建数据库连接失败! " + e.getMessage());
  return null;
  }
  pConn.setConnection(conn);
  }
  break; // 己经找到一个可用的连接,退出
  }
  }
  System.out.println("--------------:获得一个可用的数据库连接(findFreeConnection)");
  return conn;// 返回找到到的可用连接
  }
  /**
  * 测试一个连接是否可用,如果不可用,关掉它并返回 false 否则可用返回 true
  *
  * @param conn
  * 需要测试的数据库连接
  * @return 返回 true 表示此连接可用, false 表示不可用
  */
  private boolean testConnection(Connection conn) {
  try {
  // 判断测试表是否存在
  if (testTable.equals("")) {
  // 如果测试表为空,试着使用此连接的 setAutoCommit() 方法
  // 来判断连接否可用(此方法只在部分数据库可用,如果不可用 ,
  // 抛出异常)。注意:使用测试表的方法更可靠
  conn.setAutoCommit(true);
  } else {// 有测试表的时候使用测试表测试
  // check if this connection is valid
  Statement stmt = conn.createStatement();
  stmt.execute("select count(*) from " + testTable);
  }
  } catch (SQLException e) {
  // 上面抛出异常,此连接己不可用,关闭它,并返回 false;
  closeConnection(conn);
  return false;
  }
  // 连接可用,返回 true
  System.out.println("--------------:测试数据库连接是否可用");
  return true;
  }
  /**
  * 此函数返回一个数据库连接到连接池中,并把此连接置为空闲。 所有使用连接池获得的数据库连接均应在不使用此连接时返回它。
  *
  * @param 需返回到连接池中的连接对象
  */
  public void returnConnection(Connection conn) {
  System.out.println("--------------:返回到连接池中的连接对象");
  // 确保连接池存在,如果连接没有创建(不存在),直接返回
  if (connections == null) {
  System.out.println(" 连接池不存在,无法返回此连接到连接池中 !");
  return;
  }
  PooledConnection pConn = null;
  Enumeration enumerate = connections.elements();
  // 遍历连接池中的所有连接,找到这个要返回的连接对象
  while (enumerate.hasMoreElements()) {
  pConn = (PooledConnection) enumerate.nextElement();
  // 先找到连接池中的要返回的连接对象
  if (conn == pConn.getConnection()) {
  // 找到了 , 设置此连接为空闲状态
  pConn.setBusy(false);
  break;
  }
  }
  }
  /**
  * 刷新连接池中所有的连接对象
  *
  */
  public synchronized void refreshConnections() throws SQLException {
  // 确保连接池己创新存在
  if (connections == null) {
  System.out.println(" 连接池不存在,无法刷新 !");
  return;
  }
  PooledConnection pConn = null;
  Enumeration enumerate = connections.elements();
  while (enumerate.hasMoreElements()) {
  // 获得一个连接对象
  pConn = (PooledConnection) enumerate.nextElement();
  // 如果对象忙则等 5 秒 ,5 秒后直接刷新
  if (pConn.isBusy()) {
  wait(5000); // 等 5 秒
  }
  // 关闭此连接,用一个新的连接代替它。
  closeConnection(pConn.getConnection());
  pConn.setConnection(newConnection());
  pConn.setBusy(false);
  }
  }
  /**
  * 关闭连接池中所有的连接,并清空连接池。
  */
  public synchronized void closeConnectionPool() throws SQLException {
  // 确保连接池存在,如果不存在,返回
  if (connections == null) {
  System.out.println(" 连接池不存在,无法关闭 !");
  return;
  }
  PooledConnection pConn = null;
  Enumeration enumerate = connections.elements();
  while (enumerate.hasMoreElements()) {
  pConn = (PooledConnection) enumerate.nextElement();
  // 如果忙,等 5 秒
  if (pConn.isBusy()) {
  wait(5000); // 等 5 秒
  }
  // 5 秒后直接关闭它
  closeConnection(pConn.getConnection());
  // 从连接池向量中删除它
  connections.removeElement(pConn);
  }
  // 置连接池为空
  connections = null;
  }
  /**
  * 关闭一个数据库连接
  *
  * @param 需要关闭的数据库连接
  */
  private void closeConnection(Connection conn) {
  try {
  conn.close();
  } catch (SQLException e) {
  System.out.println(" 关闭数据库连接出错: " + e.getMessage());
  }
  }
  /**
  * 使程序等待给定的毫秒数
  *
  * @param 给定的毫秒数
  */
  private void wait(int mSeconds) {
  try {
  Thread.sleep(mSeconds);
  } catch (InterruptedException e) {
  }
  }
  /**
  *
  * 内部使用的用于保存连接池中连接对象的类 此类中有两个成员,一个是数据库的连接,另一个是指示此连接是否 正在使用的标志。
  */
  class PooledConnection {
  Connection connection = null;// 数据库连接
  boolean busy = false; // 此连接是否正在使用的标志,默认没有正在使用
  // 构造函数,根据一个 Connection 构告一个 PooledConnection 对象
  public PooledConnection(Connection connection) {
  this.connection = connection;
  }
  // 返回此对象中的连接
  public Connection getConnection() {
  return connection;
  }
  // 设置此对象的,连接
  public void setConnection(Connection connection) {
  this.connection = connection;
  }
  // 获得对象连接是否忙
  public boolean isBusy() {
  return busy;
  }
  // 设置对象的连接正在忙
  public void setBusy(boolean busy) {
  this.busy = busy;
  }
  }
  }
  然后新建一个测试类:
  package com.test.test;
  import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.sql.Statement;
  import com.test.util.ConnectionPoolUtil;
  public class Test {
  /**
  * @param args
  * @throws Exception
  */