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

📄 connectionpool.java

📁 大量java源程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * @(#)ConnectionPool
 *
 * Copyright (c) 1998 Karl Moss. All Rights Reserved.
 *
 * You may study, use, modify, and distribute this software for any
 * purpose provided that this copyright notice appears in all copies.
 *
 * This software is provided WITHOUT WARRANTY either expressed or
 * implied.
 *
 * @author  Karl Moss
 * @version 1.0
 * @date    11Mar98
 *
 */

package javaservlets.jdbc;

import java.sql.*;

/**
 * <p>This class serves as a JDBC connection repository. Since
 * creating database connections is one of the most time
 * intensive aspects of JDBC, we'll create a pool of connections.
 * Each connection can be used and then replaced back into the
 * pool.
 *
 * <p>A properties file 'ConnectionPool.cfg' will be used to
 * specify the types of JDBC connections to create, as well as
 * the minimum and maximum size of the pool. The format of
 * the configuration file is:
 *
 *   #(comment)
 *   JDBCDriver=<JDBC driver name>
 *   JDBCConnectionURL=<JDBC Connection URL>
 *   ConnectionPoolSize=<minimum size of the pool>
 *   ConnectionPoolMax=<maximum size of the pool, or -1 for none>
 *   ConnectionUseCount=<maximum usage count for one connection>
 *   ConnectionTimeout=<maximum idle lifetime (in minutes) of
 *        a connection>
 *   <other property for JDBC connection>=<value>
 *
 * <p>Any number of additional properties may be given (such
 * as username and password) as required by the JDBC driver.
 *
 */

public class ConnectionPool
  implements javaservlets.timer.TimerListener
{
  // JDBC Driver name
  String m_JDBCDriver;

  // JDBC Connection URL
  String m_JDBCConnectionURL;

  // Minimum size of the pool
  int m_ConnectionPoolSize;

  // Maximum size of the pool
  int m_ConnectionPoolMax;

  // Maximum number of uses for a single connection, or -1 for
  // none
  int m_ConnectionUseCount;

  // Maximum connection idle time (in minutes)
  int m_ConnectionTimeout;

  // Additional JDBC properties
  java.util.Properties m_JDBCProperties;

  // The Connection pool. This is a vector of ConnectionObject
  // objects
  java.util.Vector m_pool;

  // The maximum number of simultaneous connections as reported
  // by the JDBC driver
  int m_MaxConnections = -1;

  // Our Timer object
  javaservlets.timer.Timer m_timer;

  /**
    * <p>Initializes the ConnectionPool object using
    * 'ConnectionPool.cfg' as the configuration file
    *
    * @return true if the ConnectionPool was initialized
    * properly
    */
  public boolean initialize() throws Exception
    {
      return initialize("javaservlets/jdbc/ConnectionPool.cfg");
    }

  /**
    * <p>Initializes the ConnectionPool object with the specified
    * configuration file
    *
    * @param config Configuration file name
    * @return true if the ConnectionPool was initialized
    * properly
    */
  public boolean initialize(String config) throws Exception
    {
      // Load the configuration parameters. Any leftover parameters
      // from the configuration file will be considered JDBC
      // connection attributes to be used to establish the
      // JDBC connections
      boolean rc = loadConfig(config);

      if (rc) {
        // Properties were loaded; attempt to create our pool
        // of connections
        createPool();

        // Start our timer so we can timeout connections. The
        // clock cycle will be 20 seconds
        m_timer = new javaservlets.timer.Timer(this, 20);
        m_timer.start();
      }
      return rc;
    }

  /**
    * <p>Destroys the pool and it's contents. Closes any open
    * JDBC connections and frees all resources
    */
  public void destroy()
    {
      try {

        // Stop our timer thread
        if (m_timer != null) {
         // m_timer.stop();
          m_timer = null;
        }

        // Clear our pool
        if (m_pool != null) {

          // Loop throught the pool and close each connection
          for (int i = 0; i < m_pool.size(); i++) {
            close((ConnectionObject) m_pool.elementAt(i));
          }
        }
        m_pool = null;
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
    }

  /**
    * <p>Gets an available JDBC Connection. Connections will be
    * created if necessary, up to the maximum number of connections
    * as specified in the configuration file.
    *
    * @return JDBC Connection, or null if the maximum
    * number of connections has been exceeded
    */
  public synchronized java.sql.Connection getConnection()
    {
      // If there is no pool it must have been destroyed
      if (m_pool == null) {
        return null;
      }

      java.sql.Connection con = null;
      ConnectionObject connectionObject = null;
      int poolSize = m_pool.size();

      // Get the next available connection
      for (int i = 0; i < poolSize; i++) {

        // Get the ConnectionObject from the pool
        ConnectionObject co = (ConnectionObject)
          m_pool.elementAt(i);

        // If this is a valid connection and it is not in use,
        // grab it
        if (co.isAvailable()) {
          connectionObject = co;
          break;
        }
      }

      // No more available connections. If we aren't at the
      // maximum number of connections, create a new entry
      // in the pool
      if (connectionObject == null) {
        if ((m_ConnectionPoolMax < 0) ||
            ((m_ConnectionPoolMax > 0) &&
             (poolSize < m_ConnectionPoolMax))) {

          // Add a new connection.
          int i = addConnection();

          // If a new connection was created, use it
          if (i >= 0) {
            connectionObject = (ConnectionObject)
              m_pool.elementAt(i);
          }
        }
        else {
          trace("Maximum number of connections exceeded");
        }
      }

      // If we have a connection, set the last time accessed,
      // the use count, and the in use flag
      if (connectionObject != null) {
        connectionObject.inUse = true;
        connectionObject.useCount++;
        touch(connectionObject);
        con = connectionObject.con;
      }

      return con;
    }

  /**
    * <p>Places the connection back into the connection pool,
    * or closes the connection if the maximum use count has
    * been reached
    *
    * @param Connection object to close
    */
  public synchronized void close(java.sql.Connection con)
    {
      // Find the connection in the pool
      int index = find(con);

      if (index != -1) {
        ConnectionObject co = (ConnectionObject)
          m_pool.elementAt(index);

        // If the use count exceeds the max, remove it from
        // the pool.
        if ((m_ConnectionUseCount > 0) &&
            (co.useCount >= m_ConnectionUseCount)) {
          trace("Connection use count exceeded");
          removeFromPool(index);
        }
        else {
          // Clear the use count and reset the time last used
          touch(co);
          co.inUse = false;
        }
      }
    }

  /**
    * <p>Prints the contents of the connection pool to the
    * standard output device
    */
  public void printPool()
    {
      System.out.println("--ConnectionPool--");
      if (m_pool != null) {
        for (int i = 0; i < m_pool.size(); i++) {
          ConnectionObject co = (ConnectionObject)
            m_pool.elementAt(i);
          System.out.println("" + i + "=" + co);
        }
      }
    }

  /**
    * <p>Removes the ConnectionObject from the pool at the
    * given index
    *
    * @param index Index into the pool vector
    */
  private synchronized void removeFromPool(int index)
    {
      // Make sure the pool and index are valid
      if (m_pool != null) {

        if (index < m_pool.size()) {

          // Get the ConnectionObject and close the connection
          ConnectionObject co = (ConnectionObject)
            m_pool.elementAt(index);
          close(co);

          // Remove the element from the pool
          m_pool.removeElementAt(index);
        }
      }
    }

  /**
    * <p>Closes the connection in the given ConnectionObject
    *
    * @param connectObject ConnectionObject
    */
  private void close(ConnectionObject connectionObject)
    {
      if (connectionObject != null) {
        if (connectionObject.con != null) {
          try {

            // Close the connection
            connectionObject.con.close();
          }
          catch (Exception ex) {
            // Ignore any exceptions during close
          }

          // Clear the connection object reference
          connectionObject.con = null;
        }
      }
    }

  /**
    * <p>Loads the given configuration file.  All global
    * properties (such as JDBCDriver) will be
    * read and removed from the properties list. Any leftover
    * properties will be returned. Returns null if the
    * properties could not be loaded
    *
    * @param name Configuration file name
    * @return true if the configuration file was loaded
    */
  private boolean loadConfig(String name)
    throws Exception
    {
      boolean rc = false;

      // Get our class loader
      ClassLoader cl = getClass().getClassLoader();

      // Attempt to open an input stream to the configuration file.
      // The configuration file is considered to be a system
      // resource.
      java.io.InputStream in;

      if (cl != null) {
        in = cl.getResourceAsStream(name);
      }
      else {
        in = ClassLoader.getSystemResourceAsStream(name);
      }

      // If the input stream is null, then the configuration file
      // was not found
      if (in == null) {
        throw new Exception("ConnectionPool configuration file '" +
                           name + "' not found");
      }
      else {
        try {
          m_JDBCProperties = new java.util.Properties();

          // Load the configuration file into the properties table
          m_JDBCProperties.load(in);

          // Got the properties. Pull out the properties that we
          // are interested in
          m_JDBCDriver = consume(m_JDBCProperties, "JDBCDriver");
          m_JDBCConnectionURL = consume(m_JDBCProperties,
                                        "JDBCConnectionURL");
          m_ConnectionPoolSize = consumeInt(m_JDBCProperties,
                                            "ConnectionPoolSize");
          m_ConnectionPoolMax = consumeInt(m_JDBCProperties,
                                           "ConnectionPoolMax");
          m_ConnectionTimeout = consumeInt(m_JDBCProperties,
                                           "ConnectionTimeout");
          m_ConnectionUseCount = consumeInt(m_JDBCProperties,
                                            "ConnectionUseCount");
          rc = true;
        }
        finally {
          // Always close the input stream
          if (in != null) {
            try {
              in.close();
            }
            catch (Exception ex) {
            }
          }
        }
      }
      return rc;
    }

  /**
    * <p>Consumes the given property and returns the value.
    *
    * @param properties Properties table
    * @param key Key of the property to retrieve and remove from
    * the properties table
    * @return Value of the property, or null if not found
    */
  private String consume(java.util.Properties p, String key)

⌨️ 快捷键说明

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