⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectionpool.java

📁 采用JAVA开发
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package com.ywh.dbcp;

/**
 * <p>Title: greatom toolkit</p>
 * <p>Description: db util</p>
 * <p>Copyright: Copyright (c) 2002</p>
 * <p>Company: 北京长通联合宽带网络技术有限公司</p>
 * @author zhengzp
 * @version 1.0
 */

/**
 * add a comment test the notify function.
 * **/

import java.io.*;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;


/**
*  封装数据库连接,实现连接池。<br>
*ConnectionPool在内部维护激活连接和未激活连接两个链表,客户申请一个连接时,从未激活连接中找到一个连接,
*返回给客户,并把这个连接加入到激活连接中。用户关闭连接时,做相反的操作。
*同时,ConnectionPool使用一个后台进程定时扫描激活连接,看是否激活的时间过长了。如果是,说明程序中没有释放,
*ConnectionPool做一个记录,并关闭此连接。
*后台进程还要扫描未激活连接,执行一个简单的sql查询,如在oracle中可以执行"select * from dual;",以确保连接不会因为超时
*而断开,一旦连接断开,后台进程会重新建立连接。
* @author zhengzp
* @version 1.0
*@see java.sql.Connection
*/
public class ConnectionPool implements Serializable, IConnectionPool{
  private class ScanTask extends Thread{
    /**连接池的自动维护线程,这个线程要做两个操作:<br>
     *1、扫描激活的连接,如果连接时间过长,则认为程序没有释放,记录下错误,并释放连接。<br>
     *2、扫描未激活的连接,如果空闲时间过长,则做一次测试,即做一次简单查询,以保证连接可用。
     *   如果连接不可用,则重新生成连接。
     * */
    public void run(){
      while (!_runner.isInterrupted()) {
        synchronized (this) {
          ////log the autoscan
          cat.debug("ConnectionPool AutoScan start");
          //log.debug("ConnectionPool AutoScan start");
          long now = System.currentTimeMillis();
          ConnectionWrap cw;
          ListIterator iterator = _activeConnList.listIterator();
          while (iterator.hasNext()) {
            cw = (ConnectionWrap) iterator.next();
            if (now - cw.getDate().getTime() > overdurPeriod) {
              ////log the error
              cat.warn("ConnectionPool auto scan found a overdue active connection, the connection owner Class is " +
                       cw.getOwnerClassName());
              cat.warn("");
              //如果一个活动的连接超时,就把他从活动链表中删除,并关闭这个连接
              iterator.remove();
              --_activeConnCount;
              try {
                --_poolSize;
                cw.conn.close();
              }
              catch (SQLException e) { /*do nothing*/}
            } //if
          } //while

          iterator = _inactiveConnList.listIterator();
          while (iterator.hasNext()) {
            cw = (ConnectionWrap) iterator.next();
            if (now - cw.getDate().getTime() > testPeriod) {
              try {
                cat.debug("ConnectionPool autoscan test a connection..");
                //log.debug("ConnectionPool autoscan test a connection..");
                Statement stat = cw.createStatement();
                stat.execute(testCommand);
                stat.close();
                cw.setDate();
                cat.debug("ConnectionPool autoscan test a connection OK..");
                //log.debug("ConnectionPool autoscan test a connection OK..");
              }
              catch (SQLException e) {
                ////log the error
                cat.error(
                    "ConnectionPool auto scan test Inactive connection Error:",
                    e);
                //log.error("ConnectionPool auto scan test Inactive connection Error:",e);
                try {
                  --_poolSize;
                  iterator.remove();
                  cw.conn.close();
                }
                catch (SQLException e1) { /*do nothing*/}
                try {
                  iterator.add(createConnection());
                  ++_poolSize;
                }
                catch (SQLException e1) { /*do nothing*/}
              } //try
            } //if
          } //while
          //如果pool中的数量少于初始化的数量。在free中增加。
          while (_poolSize < initPoolSize) {
            try {
              _inactiveConnList.addLast(createConnection());
              ++_poolSize;
            }
            catch (SQLException e1) { /*do nothing*/}
          }
          //如果pool中的数量太多,应该关闭一些。
          while ( (_poolSize - _activeConnCount) > initPoolSize) {
            try {
              cw = (ConnectionWrap) _inactiveConnList.removeLast();
              cw.conn.close();
              --_poolSize;
            }
            catch (SQLException e1) {
              cat.error("close inactive connection error", e1);
            }
          }
        } //synchronized
        ////log the autoscan
        cat.debug("ConnectionPool AutoScan end");
        //log.debug("ConnectionPool AutoScan end");
        try {
          _runner.sleep(scanPeriod); //等待扫描时间,或被close方法触发
        }
        catch (InterruptedException e) {
          break;
        }
      } //while
    }
  }
//  public ini
  private static Logger cat = Logger.getLogger(ConnectionPool.class);
  private ScanTask _runner;  //后台的自动维护线程
  private LinkedList _activeConnList; //活动连接链表
  private LinkedList _inactiveConnList; //空闲连接链表
  private int _poolSize; //连接池大小
  private int _activeConnCount; //活动连续数
  private DBInfo dbInfo;
  /* the period the scaner run once,default is 10 minute*/
  private long scanPeriod=1000*60*10L;//1000*60*30l;
  /* the period we think the active connection is overdue, default is 5 minute */
  private long overdurPeriod=1000*60*5L;//1000*60*60l;
  /* the period the scaner should do a test to check inactive connection*/
  private long testPeriod = scanPeriod;
  /* the SQL command the test should excute */
  private String testCommand="select * from t_cms_tree";
  private int maxPoolSize;  //连接池的最大容量
  private int initPoolSize; //连接池的初始大小

  /**一个静态的连接池。
   * */
 // private static ConnectionPool pool;

  /**初始化缺省连接池。
   * @param config 连接池的配置,必需是xml格式
   * @return 如果成功,将静态连接池初始化,返回true,否则返回false
   * *//*

  public static boolean initial(Element config)
  {
    boolean result = false;
    DBInfo dbInfo = new DBInfo(config.getChild("database"));
    ConnectionPoolInfo poolInfo = new ConnectionPoolInfo(config);
    try
    {
      pool = new ConnectionPool(dbInfo, poolInfo);
      result = true;
    }catch(Exception e)
    {
      e.printStackTrace();
    }
    return result;
  }*/
  /**初始化缺省连接池。
   * @param fileName 一个xml格式的文件。
   * @see #initial(Element config)
   * @return 如果成功,将静态连接池初始化,返回true,否则返回false。
   * *//*
  public static boolean initial(String fileName)
  {
    boolean result = false;
    if ( pool != null )
    {
      pool.close();
    }
    try{
      InputStream in = new BufferedInputStream(new FileInputStream(fileName));
      SAXBuilder builder = new SAXBuilder();
      Document configDoc = builder.build(in);
      Element rootConfig = configDoc.getRootElement();
      result = initial(rootConfig);
    }catch(Exception t){
      t.printStackTrace();
    }
    return result;
  }*/

  /**得到一个静态连接池,全局实例
   * 可以在不同类之间共享连接池。
   * @return 得到一个静态连接池。
   *

  public static ConnectionPool getPool()
  {
    return pool;
  }*/

  public ConnectionPool(){}


  /**根据给定的连接池参数,创建一个新的连接。
   * @return 根据给定的连接池参数,创建一个新的连接*/
  private ConnectionWrap createConnection() throws SQLException{
    ConnectionWrap cw;
    try {
      cw=new ConnectionWrap(this, dbInfo.getConnection());
      cw.setDate();
    }
    catch (SQLException e){
      //log the error
      //log.error(e);
      cat.error("create connection error", e);
      throw e;
    }
    return (cw);
  }

  /**得到连接池的初始容量。
   * @return 得到连接池的初始容量。
   * */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -