defaultconnectionprovider.java

来自「Jive是基于JSP/JAVA技术构架的一个大型BBS论坛系统,这是Jive论坛」· Java 代码 · 共 939 行 · 第 1/3 页

JAVA
939
字号
                        do {                            synchronized(connStatus) {                                if((connStatus[roundRobin] < 1) &&                                        (! connPool[roundRobin].isClosed()))                                {                                    conn = connPool[roundRobin];                                    connStatus[roundRobin]=1;                                    connLockTime[roundRobin] =                                            System.currentTimeMillis();                                    connLast = roundRobin;                                    gotOne = true;                                    break;                                }                                else {                                    loop++;                                    roundRobin++;                                    if(roundRobin >= currConnections) roundRobin=0;                                }                            }                        }                        while((gotOne==false) && (loop < currConnections));                    }                    catch (SQLException e1) {}                    if(gotOne) {                        break;                    }                    else {                        synchronized(this) {  // Add new connections to the pool                            if(currConnections < maxConns) {                                try {                                    createConn(currConnections);                                    currConnections++;                                }                                catch(SQLException e) {                                    log.println("Unable to create new connection: " + e);                                }                            }                        }                        try { Thread.sleep(2000); }                        catch(InterruptedException e) {}                        log.println("-----> Connections Exhausted!  Will wait and try " +                                "again in loop " + String.valueOf(outerloop));                    }                } // End of try 10 times loop            }            else {                log.println("Unsuccessful getConnection() request during destroy()");            } // End if(available)            return conn;        }        /**         * Returns the local JDBC ID for a connection.         */        public int idOfConnection(Connection conn) {            int match;            String tag;            try {                tag = String.valueOf(this.getConnectionHash(conn));                //tag = conn.toString();            }            catch (NullPointerException e1) {                tag = "none";            }            match=-1;            for(int i=0; i< currConnections; i++) {                if(connID[i].equals(tag)) {                    match = i;                    break;                }            }            return match;        }        /**         * Frees a connection.  Replaces connection back into the main pool for         * reuse.         */        public void freeConnection(Connection conn) {            int thisconn = idOfConnection(conn);            if(thisconn >= 0) {                connStatus[thisconn]=0;            }            else {                log.println("----> Could not free connection!!!");            }        }        /**         * Returns the age of a connection -- the time since it was handed out to         * an application.         */        public long getAge(Connection conn) { // Returns the age of the connection in millisec.            int thisconn = idOfConnection(conn);            return System.currentTimeMillis() - connLockTime[thisconn];        }        /**         * Returns the same hashcode for the given object as would be returned         * by the default method hashCode(), whether or not the given object's         * class overrides hashCode().         * The hashcode for the null reference is zero.         */        private int getConnectionHash(Connection con) {            // Use of System.identifyHashCode() gets the base (java.lang.Object)            // version of the hashCode. If the Connection implementations has            // provided it's own hashCode method, it will not be used            return System.identityHashCode(con);        }        private void createConn(int i) throws SQLException {            Date now = new Date();            try {                Class.forName(dbDriver);                if (mysqlUseUnicode) {                    Properties props = new java.util.Properties();                    props.put("characterEncoding", JiveGlobals.getCharacterEncoding());                    props.put("useUnicode", "true");                    props.put("user", dbLogin);                    props.put("password", dbPassword);                    connPool[i] = DriverManager.getConnection(dbServer, props);                }                else {                    connPool[i] = DriverManager.getConnection(dbServer,dbLogin,dbPassword);                }                connStatus[i] = 0;                connID[i] = String.valueOf(getConnectionHash(connPool[i]));                connLockTime[i] = 0;                connCreateDate[i] = now.getTime();                log.println(now.toString() + "  Opening connection " + String.valueOf(i) +                    " " + connPool[i].toString() + ":");            }            catch (ClassNotFoundException e2) {                e2.printStackTrace();                throw new SQLException(e2.getMessage());            }        }        /**         * Shuts down the housekeeping thread and closes all connections         * in the pool. Call this method from the destroy() method of the servlet.         */        /**         * Multi-phase shutdown.  having following sequence:         * <OL>         * <LI><code>getConnection()</code> will refuse to return connections.         * <LI>The housekeeping thread is shut down.<br>         *    Up to the time of <code>millis</code> milliseconds after shutdown of         *    the housekeeping thread, <code>freeConnection()</code> can still be         *    called to return used connections.         * <LI>After <code>millis</code> milliseconds after the shutdown of the         *    housekeeping thread, all connections in the pool are closed.         * <LI>If any connections were in use while being closed then a         *    <code>SQLException</code> is thrown.         * <LI>The log is closed.         * </OL><br>         * Call this method from a servlet destroy() method.         *         * @param      millis   the time to wait in milliseconds.         * @exception  SQLException if connections were in use after         * <code>millis</code>.         */        public void destroy(int millis) throws SQLException {            // Checking for invalid negative arguments is not necessary,            // Thread.join() does this already in runner.join().            // Stop issuing connections            available=false;            // Shut down the background housekeeping thread            runner.interrupt();            // Wait until the housekeeping thread has died.            try { runner.join(millis); }            catch(InterruptedException e){} // ignore            // The housekeeping thread could still be running            // (e.g. if millis is too small). This case is ignored.            // At worst, this method will throw an exception with the                // clear indication that the timeout was too short.            long startTime=System.currentTimeMillis();            // Wait for freeConnection() to return any connections            // that are still used at this time.            int useCount;            while((useCount=getUseCount())>0 && System.currentTimeMillis() -                    startTime <=  millis)            {                try { Thread.sleep(500); }                catch(InterruptedException e) {} // ignore            }            // Close all connections, whether safe or not            for(int i=0; i < currConnections; i++) {                try {                    connPool[i].close();                }                catch (SQLException e1)                {                    log.println("Cannot close connections on Destroy");                }            }            if(useCount > 0) {                //bt-test successful                String msg="Unsafe shutdown: Had to close "+useCount+                            " active DB connections after "+millis+"ms";                log.println(msg);                // Close all open files                log.close();                // Throwing following Exception is essential because servlet authors                // are likely to have their own error logging requirements.                throw new SQLException(msg);            }            // Close all open files            log.close();        }//End destroy()        /**         * Less safe shutdown.  Uses default timeout value.         * This method simply calls the <code>destroy()</code> method         * with a <code>millis</code>         * value of 10000 (10 seconds) and ignores <code>SQLException</code>         * thrown by that method.         * @see     #destroy(int)         */        public void destroy() {            try {                destroy(10000);            }            catch(SQLException e) {}        }        /**         * Returns the number of connections in use.         */        // This method could be reduced to return a counter that is        // maintained by all methods that update connStatus.        // However, it is more efficient to do it this way because:        // Updating the counter would put an additional burden on the most        // frequently used methods; in comparison, this method is        // rarely used (although essential).        public int getUseCount() {            int useCount=0;            synchronized(connStatus) {                for(int i=0; i < currConnections; i++) {                    if(connStatus[i] > 0) { // In use                        useCount++;                    }                }            }            return useCount;        }//End getUseCount()        /**         * Returns the number of connections in the dynamic pool.         */        public int getSize() {            return currConnections;        }//End getSize()    } // End class    /**     * An implementation of the Connection interface that wraps an underlying     * Connection object. It releases the connection back to a connection pool     * when Connection.close() is called.     */    public class ConnectionWrapper extends ConnectionAdapter {        private ConnectionPool connectionPool;        public ConnectionWrapper(Connection connection, ConnectionPool connectionPool) {            super(connection);            this.connectionPool = connectionPool;        }        /**         * Instead of closing the underlying connection, we simply release         * it back into the pool.         */        public void close() throws SQLException {            connectionPool.freeConnection(this.connection);            //Release object references. Any further method calls on the            //connection will fail.            connection = null;            connectionPool = null;        }        public String toString() {            if (connection != null) {                return connection.toString();            }            else {                return "Jive Software Cnnection Wrapper";            }        }    }}

⌨️ 快捷键说明

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