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

📄 connectionpool.java

📁 java 写的一个新闻发布系统
💻 JAVA
字号:
package org.jahia.services.database;import java.sql.*;import java.util.*;import org.jahia.utils.*;           // JahiaConsole/** * <p>Title: ConnectionPool </p> * <p>Description: manages a connection pool to a JDBC database. This * implementation uses threads to create connection on demand, and * synchronisation to wait for the created connections</p> * <p>Basically the only interesting methods in here are the constructor, * the getConnection and the free methods. The rest will only be needed * in some status cases, etc..</p> * <p>Copyright: Copyright (c) 2002</p> * <p>Company: Jahia Inc.</p> */public class ConnectionPool implements Runnable{    private String  db_driver;    private String  db_url;    private String  db_username;    private String  db_password;    private int     minConnections;    private int     maxConnections;    private boolean waitIfBusy;    // the vector of connections that are available in the pool    private Vector  availableConnections    = new Vector();    // the vector of connections that are unavailable in the pool,    // currently busy processing requests    private Vector  busyConnections         = new Vector();    // connectionPending is true if there is a thread currently    // opening a connection to the database    private boolean connectionPending       = false;    // used to display debug messages if activated in constructor    private boolean verbose                 = true;    /**     * Constructor for a connection pool object.     * @param db_driver JDBC driver name to use     * @param db_url JDBC URL to use to connect to the database     * @param db_username JDBC username to connect to the database     * @param db_password JDBC password to connect to the database     * @param initialConnections number of initial connection to initialize     * the pool with     * @param maxConnections maximum number of database connections open     * simultaneously in pool     * @param waitIfBusy boolean that indicates if we should wait if all     * the connections in the pool are already occupied, otherwise will     * return with an exception     * @param verbose boolean that activates debug messages for the     * pool, helping debugging and diagnosticating database connection     * problems (such as connection timeout, etc...)     * @throws SQLException     */    public ConnectionPool(  String  db_driver,                            String  db_url,                            String  db_username,                            String  db_password,                            int     initialConnections,                            int     maxConnections,                            boolean waitIfBusy,                            boolean verbose )    throws SQLException    {        toConsole( "ConnectionPool",                   "New connection pool object in creation... " );        // sets private vars        this.db_driver      = db_driver;        this.db_url         = db_url;        this.db_username    = db_username;        this.db_password    = db_password;        this.minConnections = initialConnections;        this.maxConnections = maxConnections;        this.waitIfBusy     = waitIfBusy;        this.verbose        = verbose;        toConsole("ConnectionPool", "verbose is " + verbose );        // nothing's foolproof...        if (initialConnections > maxConnections) {            initialConnections = maxConnections;        }        availableConnections = new Vector(initialConnections);        // create initial connections        for (int i=0; i < initialConnections; i++) {            availableConnections.addElement( makeNewConnection() );        }    } // end ConnectionPool    /**     * Retrieves a connection from the connection pool, creating it if     * necessary     * @param debugID an identifier useful for debugging retrieval and     * freeing connection pool entries     * @return a JDBC connection object that is an open connection to the     * database     * @throws SQLException     */    public synchronized Connection getConnection(int debugID)    throws SQLException    {        toConsole( "getConnection" ,                   "Trying to serve (DEBUGID : "+debugID+"; available : " +                   availableConnections.size() + "; busy : " +                   busyConnections.size() + ")" );        // quick sanity check        if (getTotalConnections() < minConnections) {            toConsole("getConnection",                      "Warning : current number of connnections below minimum pool size !");        }        // checks it there are available connections left        if (!availableConnections.isEmpty()) {            // if yes, grab a connection            Connection existingConnection = (Connection) availableConnections.lastElement();            int lastIndex = availableConnections.size() - 1;            // remove the connection we just taked            availableConnections.removeElementAt( lastIndex );            // check if the connection is still open            if (existingConnection.isClosed()) {                toConsole( "getConnection",                           "Connection retrieved from available connection is already closed, waiting for a new one ...");                // if closed, notify all waiting threads that a connection can be created                notifyAll();                // then retry                return ( getConnection(90) );            } else {                // not closed, add the connection to the busyConnections array                // and return it                busyConnections.addElement( existingConnection );                return existingConnection;            }        } else {            // if no more connections available            // check if we can add a connection (max not reached)            if ((getTotalConnections() < maxConnections) && (!connectionPending)) {                // create one connection in the background                makeBackgroundConnection();            } else if (!waitIfBusy) {                // can't add new connections                // can't wait                // => scream !!                throw new SQLException( "Connection limit reached" );            }            // try to grab one            try {                // wait that one frees up                wait();            } catch (InterruptedException ie) {                // then go and grab it !            }            return ( getConnection(91) );        }    } // end getConnection    /**     * Creates a database connection using a thread to initialize it.     * @todo FIXME : what happens when OutOfMemoryError occurs ?     */    private void makeBackgroundConnection()    {        toConsole( "makeBackgroundConnection" ,                   "Creating a background Connection via a thread" );        // we're trying to create a new connection here        connectionPending = true;        // launch the background thread        try {            Thread connectionThread = new Thread( this );            connectionThread.start();   // calls the run() method        } catch (OutOfMemoryError memError) {            toConsole ( "makeBackGroundConnection",                        "Out of memory exception during background thread connnection creation");            JahiaConsole.printe("ConnectionPool.makeBackgroundConnection", memError);            // scream !        }    } // makeBackgrounConnection    /**     * Method called when the thread is created to run the creation of a     * single database connection.     * @todo FIXME : what happens when SQLException or OutOfMemoryError ?     */    public void run()    {        toConsole( "run",                   "Starting a new ConnectionPool Thread to create a database connnection" );        try {            // try to create a new connection            Connection newConnection = makeNewConnection();            synchronized( this ) {                // stores it in the available connection array                availableConnections.addElement( newConnection );                // end of the operation -> connection is no more pending                connectionPending = false;                // say to all waiting threads that a new connection is ready                notifyAll();            }        } catch (Exception e) {            JahiaConsole.printe("ConnectionPool.run", e);            // SQLException or OutOfMemoryError            // scream !        }    } // end run    /**     * Creates a single database connection and returns it     * @return a JDBC connection object that has been opened     * @throws SQLException an exception generated in case of problems     * opening the connection to the database     */    private Connection makeNewConnection()    throws SQLException    {        toConsole( "makeNewConnection", "Creating a new connection" );        try {            // load database driver            Class.forName( db_driver );            // establish connection            Connection newConnection = DriverManager.getConnection( db_url, db_username, db_password );            return newConnection;        } catch (ClassNotFoundException cnfe) {            // scream !!            throw new SQLException( "Can't find class to driver : " + db_driver );        }    } // end run    /**     * Frees a connection and returns it into the pool of connections.     * @param theConnection the connnection to return into the available     * pool     * @todo FIXME does not verify the status of the connection, maybe we     * want to introduce that later for better stability ?     */    public synchronized void free( Connection theConnection )    {        toConsole( "free", "Trying to free a connection (available : "            + availableConnections.size() + "; busy : " + busyConnections.size() + ")" );        // remove connection form busyConnections array        busyConnections.removeElement( theConnection );        // add it to the availableConnecitons array        availableConnections.addElement( theConnection );        // notify all waiting threads that a new connection is free        notifyAll();    } // end free    /**     * Returns the number of connections both in the busy state and in     * the available pool. Basically this returns the number of connections     * to the database that are handled by this connection pool at the     * current time     * @return an integer representing the sum of the available pool and     * the currently used connections.     */    public synchronized int getTotalConnections()    {        return ( availableConnections.size() + busyConnections.size() );    } // end totalConnections    /**     * Returns the number of available connections in the pool.     * @return an integer that represents the size of the available     * connections.     */    public int getNbFreeConnections()    {        return ( availableConnections.size() );    } // end totalFreeConnections    /**     * Returns the number of connections managed by this pool that are not     * available (ie are busy handling SQL queries)     * @return an integer representing the number of busy queries     */    public int getBusyConnections() {        return busyConnections.size();    }    /**     * Returns the configured minimum size of the connection pool     * @return an integer representing the minimum size of the pool as     * configured via the constructor     */    public int getMinConnections() {        return this.minConnections;    }    /**     * Returns the configured maximum size of the connection pool     * @return an integer representing the maximum size of the pool as configured     * via the constructor     */    public int getMaxConnections() {        return this.maxConnections;    }    /**     * This method is used mostly to destroy all the connections managed     * by this pool. This should ONLY be called in extreme cases such as     * a requested shutdown as it does NOT reinitialize the pool and doesn't     * re-open any connections. Please use with caution.     */    public synchronized void closeAllConnections()    {        toConsole( "closeAllConnections", "Closing all connections !" );        closeConnections( availableConnections );        availableConnections = new Vector();        closeConnections( busyConnections );        busyConnections = new Vector();    } // end closeAllConnections    /**     * Closes a vector of connections.     * @param connections a vector of connection objects     */    private void closeConnections( Vector connections )    {        toConsole( "closeConnections", "Closing connection" );        try {            for (int i=0; i < connections.size(); i++) {                Connection theConnection = (Connection) connections.elementAt( i );                if (!theConnection.isClosed()) {                    theConnection.close();                }            }        } catch (SQLException se) {            JahiaConsole.printe("ConnectionPool.closeConnections", se);            // anyway... garbage collector's taking care of the dirty work        }    } // end closeConnections    /**     * Displays a message on the Jahia console. Do not use this method     * to display exceptions but prefer the use of JahiaConsole.printe()     * instead.     * @param method name of the method for which to display this message     * @param msg the message itself to display     */    private void toConsole( String method, String msg )    {        if (verbose) {            JahiaConsole.println("ConnectionPool." + method, msg );        }    } // end toConsole}

⌨️ 快捷键说明

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