还有个内部类:
/**
 * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
 */
class DBConnectionPool {
private int checkedOut;
private List freeConnections = new LinkedList();
private int maxConn;
private String name;
private String password;
private String URL;
private String user;
private Hashtable checkedOutList = new Hashtable();
private Timer timer1;
private Timer timer2;
public List scheduleThreads = new LinkedList();
/**
 * 创建新的连接池
 * 
 * @param name
 *            连接池名字
 * @param URL
 *            数据库的JDBC URL
 * @param user
 *            数据库帐号,或 null
 * @param password
 *            密码,或 null
 * @param maxConn
 *            此连接池允许建立的最大连接数
 */
public DBConnectionPool(String name, String URL, String user,
String password, int maxConn) {
this.name = name;
this.URL = URL;
this.user = user;
this.password = password;
this.maxConn = maxConn;
timer1 = new Timer();
timer1.schedule(new FreeConThread(), DBConnectionManager.checktime,
DBConnectionManager.checktime);
timer2 = new Timer();
timer2.schedule(new ReBuildConThread(),
DBConnectionManager.rebuildtime,
DBConnectionManager.rebuildtime);
}

/**
 * 将不再使用的连接返回给连接池
 * 
 * @param con
 *            客户程序释放的连接
 */
public synchronized void freeConnection(Connection con) {
// 将指定连接加入到向量末尾
freeConnections.add(con);
checkedOut--;
checkedOutList.remove(con);
notifyAll();
// if(strDetail.equals("1"))
// {
// log("连接池" + name + "的连接(" + con.toString() + ")使用完毕!");
// } } /**
 * 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
 * 然后递归调用自己以尝试新的可用连接.
 */
public synchronized Connection getConnection() { Connection con = null;
final double conMaxRate = 0.9;
if (freeConnections.size() > 0) {
// 获取向量中第一个可用连接
con = (Connection) freeConnections.get(0);
freeConnections.remove(0);
try {
if (con.isClosed()) {
// log("从连接池" + name + "删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getConnection();
// log(new
// StringBuffer("连接池").append(name).append("创建一个新的连接(").append(maxConn).append(",").append((checkedOut
// + 1)).append(")").toString());
}
} catch (SQLException e) {
// log("从连接池" + name + "删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getConnection();
// log(new
// StringBuffer("连接池").append(name).append("创建一个新的连接(").append(maxConn).append(",").append((checkedOut
// + 1)).append(")").toString());
}
} else if (maxConn == 0 || checkedOut < (int)(maxConn*conMaxRate)) {
con = newConnection();
} else if (maxConn != 0 && checkedOut >= (int)(maxConn*conMaxRate)) {
shrinkList();
freeList() ;
con = newConnection();
//手动回收占用的连接
}
else if (maxConn != 0 && checkedOut >= (int)(maxConn)) {
shrinkList();
freeList() ;
//超过阈值
}
else {
log("连接池溢出!");
}
if (con != null) {
checkedOut++;
Date now = new Date();
checkedOutList.put(con, now);
if (intDetail >= 2)
try {
throw new Exception();
} catch (Exception ex) {
StackTraceElement[] stack = ex.getStackTrace();
log(new StringBuffer("ID: ").append(now.getTime())
.append(" ").append(stack[2].toString())
.toString());
}
// if(strDetail.equals("1"))
// {
// log("连接池" + name + "的连接(" + con.toString() + ")正在使用中...");
// }
}
return con;
} /**
 * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间 参见前一个getConnection()方法.
 * 
 * @param timeout
 *            以毫秒计的等待时间限制
 */
public synchronized Connection getConnection(long timeout) {
long startTime = new Date().getTime();
Connection con;
while ((con = getConnection()) == null) {
try {
wait(timeout);
} catch (InterruptedException e) {
}
if ((new Date().getTime() - startTime) >= timeout) {
// wait()返回的原因是超时
return null;
}
}
return con;
} /**
 * 关闭连接池中的所有连接(暂时不对外使用)
 */
public synchronized void release() {
Iterator i = freeConnections.iterator();
while (i.hasNext()) {
Connection con = (Connection) i.next();
try {
con.close();
log("关闭连接池" + name + "中的一个连接");
} catch (SQLException e) {
log(e, "无法关闭连接池" + name + "中的连接");
}
}
freeConnections.clear();
Enumeration eum = checkedOutList.keys();
while (eum.hasMoreElements()) {
try {
((Connection) eum.nextElement()).close();
} catch (SQLException ex) { } }
} /**
 * 创建新的连接
 */
private synchronized Connection newConnection() {
Connection con = null;
try {
if (user == null) {
con = DriverManager.getConnection(URL);
} else {
con = DriverManager.getConnection(URL, user, password);
}
System.out.println(new StringBuffer("连接池").append(name).append("创建一个新的连接(")
.append(maxConn).append(",").append((checkedOut + 1))
.append(")").toString());
//log(new StringBuffer("连接池").append(name).append("创建一个新的连接(")
// .append(maxConn).append(",").append((checkedOut + 1))
// .append(")").toString());
} catch (SQLException e) {
log(e, "无法创建下列URL的连接: " + URL);
return null;
}
return con;
} public synchronized void shrinkList() {
// log("rebuild db pool in " + name);
Iterator i = freeConnections.iterator();
while (i.hasNext()) {
if (freeConnections.size() <= DBConnectionManager.shrinkCnt) {
break;
}
Connection con = (Connection) i.next();
try {
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
i.remove();
}
Iterator j = scheduleThreads.iterator();
while(j.hasNext()){
System.out.println("aaaaa");
TimerTask temp = (TimerTask)j.next();
System.out.println("TimerTask execution time : "+temp.scheduledExecutionTime());
System.out.println("bbbbb");
}
// log("shrink connection to " +
// String.valueOf(freeConnections.size()) + "should be "+
// String.valueOf(DBConnectionManager.shrinkCnt) +" in "+ name);
} public  void freeList() {
// log("check the db pool in " + name);
java.util.Enumeration checkedOutKey = checkedOutList.keys();
while (checkedOutKey.hasMoreElements()) {
Connection con = (Connection) checkedOutKey.nextElement();
java.util.Date oldDate = (java.util.Date) checkedOutList
.get(con);
Object obj;
if (System.currentTimeMillis() - oldDate.getTime() >= DBConnectionManager.timeout) {
System.out.println(new StringBuffer(
"find a overflow connection close one in ").append(
name).append(" ").append("ID: ").append(
oldDate.getTime()).toString());
//log(new StringBuffer(
// "find a overflow connection close one in ").append(
// name).append(" ").append("ID: ").append(
// oldDate.getTime()).toString());
try {
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
checkedOutList.remove(con);
checkedOut--;
}
}
} private class FreeConThread extends java.util.TimerTask { public void run() {
freeList();
}
} private class ReBuildConThread extends java.util.TimerTask { public void run() {
shrinkList();
}
}
}