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 + -
显示快捷键?