📄 connectionpool.java
字号:
for (int outerloop = 1; outerloop <= 10; outerloop++) { // try ten
// times to
// find one.
try {
int loop = 0;
int roundRobin = connLast + 1;
if (roundRobin >= currConnections) {
roundRobin = 0;
}
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; // break the outer loop
} else {
synchronized (this) { // Add new connections to the pool
if (currConnections < maxconns) {
try {
createConn(currConnections);
currConnections++;
} catch (SQLException e) {
System.out
.println("Unable to create new connection: "
+ String
.valueOf(currConnections - 1));
System.out.println("Exception : " + e);
}
} // if
} // synchronized
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out
.println("-----> Connections Exhausted! Will wait and try "
+ "again in outer loop "
+ String.valueOf(outerloop));
}
} // End of try 10 times loop
} else { // not available
System.out
.println("Unsuccessful getConnection() request during destroy()");
} // End if(available)
return conn;
}
/**
* Returns the local JDBC ID for a connection. if there's not the connection
* int the pool return -1
*/
public int idOfConnection(Connection conn) {
int match;
String tag;
try {
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 String freeConnection(Connection conn) {
String res = "";
int thisconn = idOfConnection(conn);
if (thisconn >= 0) {
connStatus[thisconn] = 0;
res = "freed " + conn.toString();
// log("Freed connection " + String.valueOf(thisconn) +
// " normal exit: ");
} else {
System.out.println("----> Could not free connection!!!"
+ "Try to close it directly");
try {
conn.close();
} catch (SQLException e) {
}
}
return res;
}
/**
* 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];
}
/**
* 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) {
System.out.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";
System.out.println(msg);
// Throwing following Exception is essential because servlet authors
// are likely to have their own error logging requirements.
throw new SQLException(msg);
}
} // 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()
public static void main(String[] args) {
String driver = "org.gjt.mm.mysql.Driver";
String server = "jdbc:mysql://127.0.0.1/elearning?autoReconnect=true";
String dbuser = "root";
String dbpassword = "";
int minconn = 5;
int maxconn = 20;
double maxconntime = 0.1D;
try {
ConnectionPool p = new ConnectionPool(driver, server, dbuser,
dbpassword, minconn, maxconn, maxconntime);
} catch (IOException e) {
e.printStackTrace();
}
}
} // end class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -