正文

一个不错的连接池2006-05-24 09:56:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/ggbm/14767.html

分享到:

            以前在网上看到一个别人写的连接池,很收启发,但是不记得那位仁兄的名字了,:)今天把它拿出来,改了下,还希望那位仁兄不要“骂”我啊。。嘿嘿。。。     /* * Created on 2006-5-24 9:23:26 *  * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates * ===============Version 1.0.0.0====================== */package com; import java.sql.*;import java.util.*;import java.io.*;import com.log.Logger; /** * @author 李国庆 *  * Project: Test Package: com ClassName: ConnectionPool */public class ConnectionPool implements TimerListener {    // Keep a static ConnectionPool for singleton    private static ConnectionPool connectionPool;     // Driver name    String jdbcDriver;     // Connection URL    String jdbcConnectionURL;     // Minimum size of the pool    int connectionPoolSize;     // Maximum size of the pool    int connectionPoolMax;     // Maximum number of uses for a single connection, or -1 for    // none    int connectionUseCount;     // Maximum connection idle time (in minutes)    int connectionTimeout;     // The connection pool scan interval;    int scanInterval;     // Additional JDBC properties    Properties jdbcProperties;     // The Connection pool. This is a vector of ConnectionObject    // objects    Vector pool;     // The maximum number of simultaneous connections as reported    // by the JDBC driver    int maxConnections = -1;     // Our Timer object    Timer timer;     /**     * Empty Constructor     */    private ConnectionPool() throws Exception {        initialize();    }     /**     * <p&rt;Initializes the ConnectionPool object using ´database.conf´ under     * the WEB-INF/classes as the configuration file     *      * @return true if the ConnectionPool was initialized properly     */     private boolean initialize() throws Exception {        return initialize("database.conf");    }     /**     * <p&rt;Initializes the ConnectionPool object with the specified     * configuration file     *      * @param config     *            Configuration file name     * @return true if the ConnectionPool was initialized properly     */    private boolean initialize(String config) throws Exception {         boolean rc = loadConfig(config);         if (rc) {             Logger.println("Creating the pool....");            createPool();             timer = new Timer(this, scanInterval);            timer.start();        }         return rc;    }     {     }     /**     * <p&rt;Destroys the pool and it´s contents. Closes any open JDBC     * connections and frees all resources     */    public void destroy() {        try {             if (timer != null) {                timer.destroy();                timer = null;            }             if (pool != null) {                 for (int i = 0; i < pool.size(); i++) {                    close((ConnectionObject) pool.elementAt(i));                }            }            pool = null;        }        catch (Exception ex) {            ex.printStackTrace();        }    }     /**     * Create single ConnectionPool if there is not ConnectionPool     *      * @param none     * @return Static ConnectionPool     */     public static ConnectionPool getInstance() throws Exception {        if (connectionPool == null) {            connectionPool = new ConnectionPool();        }        return connectionPool;    }     /**     * <p&rt;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 Connection getConnection()  {   if (pool == null)   {       return null;   }    java.sql.Connection con = null;   ConnectionObject connectionObject = null;   ConnectionObject co = null;   int poolSize = pool.size();     for (int i = 0; i < poolSize; i++)   {          co = (ConnectionObject) pool.elementAt(i);    if (co.isAvailable())    {        connectionObject = co;        break;    }   }   if (connectionObject == null)   {       if ((connectionPoolMax < 0) || ((connectionPoolMax &rt; 0) && (poolSize < connectionPoolMax)))       {           int i = addConnection();     if (i &rt;= 0) {         connectionObject = (ConnectionObject)pool.elementAt(i);     }       }      else {           Logger.println("Maximum number of connections exceeded");       }   }     if (connectionObject != null)   {    connectionObject.inUse = true;    connectionObject.useCount++;    touch(connectionObject);    con = connectionObject.con;   }     return con;  }    /**     * <p&rt;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(Connection aCon)  {   int index = find(aCon);      if (index != -1)   {    ConnectionObject co = (ConnectionObject)pool.elementAt(index);     if ((connectionUseCount &rt; 0) && (co.useCount &rt;= connectionUseCount))    {     Logger.println("Connection use count exceeded");     removeFromPool(index);    }    else    {     touch(co);     co.inUse = false;    }  } }    /**     * <p&rt;Prints the contents of the connection pool to the standard output     * device, test the Pool content     */    public void printPool() {        System.out.println("--ConnectionPool--");        if (pool != null) {            for (int i = 0; i < pool.size(); i++) {                ConnectionObject co = (ConnectionObject) pool.elementAt(i);                System.out.println("" + i + "=" + co);            }        }    }     /**     * <p&rt;Removes the ConnectionObject from the pool at the given index     *      * @param index     *            Index into the pool vector     */ private synchronized void removeFromPool(int index)  {   if (pool != null)   {    if (index < pool.size() && (index &rt;= 0))    {     ConnectionObject co = (ConnectionObject)pool.elementAt(index);     close(co);     pool.removeElementAt(index);    }   } }    /**     * <p&rt;Closes the connection in the given ConnectionObject     *      * @param connectObject     *            ConnectionObject     */    private void close(ConnectionObject connectionObject) {        if (connectionObject != null) {            if (connectionObject.con != null) {                try {                    connectionObject.con.close();                }                catch (Exception ex) {                 }                 connectionObject.con = null;            }        }    }     /**     * <p&rt;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;        try {            jdbcProperties = lc.getConfigProperties(name);            if (jdbcProperties == null)                rc = false;            else {                jdbcDriver = consume(jdbcProperties, "DriverName");                jdbcConnectionURL = consume(jdbcProperties, "URL");                connectionPoolSize = consumeInt(jdbcProperties,                        "ConnectionPoolSize");                connectionPoolMax = consumeInt(jdbcProperties,                        "ConnectionPoolMax");                connectionUseCount = consumeInt(jdbcProperties,                        "ConnectionUseCount");                connectionTimeout = consumeInt(jdbcProperties,                        "ConnectionTimeout");                scanInterval = consumeInt(jdbcProperties, "ScanInterval");                rc = true;            }        }        catch (Exception e) {            Logger                    .println("<Exception&rt;[ConnectionPool]Exception occured while loading config"); // Clean            // memory            throw new Exception (                    "Exception while loading the config");        }        return rc;    }     /**     * <p&rt;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) {        String s = null;         if ((p != null) && (key != null)) {            s = p.getProperty(key);            if (s != null) {                p.remove(key);            }        }        return s;    }     /**     * <p&rt;Consumes the given property and returns the integer 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 -1 if not found     */    private int consumeInt(java.util.Properties p, String key) {        int n = -1;         String value = consume(p, key);        if (value != null) {            try {                n = Integer.parseInt(value);            }            catch (NumberFormatException ex) {                ex.printStackTrace();            }        }        return n;    }     /**     * <p&rt;Creates the initial connection pool. A timer thread is also created     * so that connection timeouts can be handled.     *      * @return true if the pool was created     */    private void createPool() throws Exception {        if (jdbcDriver == null) {            throw new Exception("JDBCDriver property not found");        }        if (jdbcConnectionURL == null) {            throw new Exception("JDBCConnectionURL property not found");        }        if (connectionPoolSize < 0) {            throw new Exception("ConnectionPoolSize property not found");        }        if (connectionPoolSize == 0) {            throw new Exception("ConnectionPoolSize invalid");        }        if (connectionPoolMax < connectionPoolSize) {            Logger.println("WARNING - ConnectionPoolMax is invalid and will "                    + "be ignored");            connectionPoolMax = -1;        }        if (connectionTimeout < 0) {            connectionTimeout = 30;        }         Logger.println("JDBCDriver = " + jdbcDriver);        Logger.println("JDBCConnectionURL = " + jdbcConnectionURL);        Logger.println("ConnectionPoolSize = " + connectionPoolSize);        Logger.println("ConnectionPoolMax = " + connectionPoolMax);        Logger.println("ConnectionUseCount = " + connectionUseCount);        Logger.println("ConnectionTimeout = " + connectionTimeout + " seconds");        Logger.println("ScanInterval = " + scanInterval + " seconds");        Logger.println("Registering " + jdbcDriver);         java.sql.Driver d = (java.sql.Driver) Class.forName(jdbcDriver)                .newInstance();        pool = new java.util.Vector();        fillPool(connectionPoolSize);    }     /**     * <p&rt;Adds a new connection to the pool     *      * @return Index of the new pool entry, or -1 if an error has occurred     */    private int addConnection() {        int index = -1;         try {             int size = pool.size() + 1;            fillPool(size);            if (size == pool.size()) {                index = size - 1;            }        }        catch (Exception ex) {            ex.printStackTrace();        }        return index;    }     /**     * <p&rt;Brings the pool to the given size     *      * @size Size of the pool entry     */ private synchronized void fillPool(int size) throws Exception  {   String userID = null;   String password = null;   if (jdbcProperties != null)   {      userID = getPropertyIgnoreCase(jdbcProperties, "UserName");    password = getPropertyIgnoreCase(jdbcProperties, "UserPassword");    if (userID == null) userID = "admin";    if (password == null) password = "";   }    while (pool.size() < size) {       ConnectionObject co = new ConnectionObject();        co.con = DriverManager.getConnection(jdbcConnectionURL, userID, password);        if (pool.size() == 0)    {     java.sql.DatabaseMetaData md = co.con.getMetaData();     maxConnections = md.getMaxConnections();    }       if ((maxConnections &rt; 0) && (size &rt; maxConnections))    {        Logger.println("WARNING: Size of pool will exceed safe maximum of " +maxConnections);    }    co.inUse = false;    touch(co);       pool.addElement(co);   }  }    /**     * Gets a the named propery, ignoring case. Returns null if not found     *      * @param p     *            The property set     * @param name     *            The property name     * @return The value of the propery, or null if not found     */    private String getPropertyIgnoreCase(java.util.Properties p, String name) {        if ((p == null) || (name == null))            return null;         String value = null;         java.util.Enumeration enum = p.propertyNames();         while (enum.hasMoreElements()) {            String pName = (String) enum.nextElement();            if (pName.equalsIgnoreCase(name)) {                value = p.getProperty(pName);                break;            }        }         return value;    }     /**     * <p&rt;Find the given connection in the pool     *      * @return Index into the pool, or -1 if not found     */    private int find(java.sql.Connection aCon) {        int index = -1;         if ((aCon != null) && (pool != null)) {            for (int i = 0; i < pool.size(); i++) {                ConnectionObject co = (ConnectionObject) pool.elementAt(i);                if (co.con == aCon) {                    index = i;                    break;                }            }        }        return index;    }     /**      * <p&rt;Called by the timer each time a clock cycle expires.      * This gives us the opportunity to timeout connections      */ public synchronized void TimerEvent(Object object)  {   if (pool == null)   {       return;   }   long now = System.currentTimeMillis();   for (int i = pool.size() - 1; i &rt;= 0; i--)   {    ConnectionObject co = (ConnectionObject) pool.elementAt(i);    if (!co.inUse)    {     if ((connectionTimeout &rt; 0) && (co.lastAccess +(connectionTimeout * 1000) < now))     {         removeFromPool(i);     }    }   }     for (int i = pool.size() - 1; i &rt;= 0; i--)   {       ConnectionObject co = (ConnectionObject)pool.elementAt(i);   try   {    // If the connection is closed, remove it from the pool    if (co.con.isClosed())    {     Logger.println("Connection closed unexpectedly");     removeFromPool(i);    }   }   catch (Exception ex) { }   }     try   {    if (pool != null)    {     if (pool.size() < connectionPoolSize)     {         fillPool(connectionPoolSize);     }    }   }   catch (Exception ex)   {       ex.printStackTrace();   }  } /**   * <p&rt;Sets the last access time for the given ConnectionObject   */ private void touch(ConnectionObject co) {     if (co != null) {         co.lastAccess = System.currentTimeMillis();     } }     /** public static void main(String arg[]) throws Exception       {       ConnectionPool connectionPool = ConnectionPool.getInstance();       System.out.println("Hello World");       }       */ }   /* * Created on 2006-5-24 9:23:26 *  * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates * ===============Version 1.0.0.0====================== */package com; /** * @author 李国庆 *  * Project: Test Package: com ClassName: ConnectionPool */ public class ConnectionObject {    // The JDBC Connection     public java.sql.Connection con;     // true if this connection is currently in use     public boolean inUse;     // The last time (in milliseconds) that this connection was used     public long lastAccess;     // The number of times this connection has been used     public int useCount;     /**      * <p&rt;Determine if the connection is available      *      * @return true if the connection can be used      */    public boolean isAvailable() {        boolean available = false;         try {             if (con != null) {                if ((!inUse) && (!con.isClosed())) {                    available = true;                }            }        }        catch (Exception ex) {        }         return available;    }     /**      * <p&rt;Convert the object contents to a String      */    public String toString() {        return "Connection=" + con + ",inUse=" + inUse + ",lastAccess="                + lastAccess + ",useCount=" + useCount;    }}

阅读(2618) | 评论(2)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册