日期:2014-05-16 浏览次数:20650 次
上次写的连接池一旦得不到连接就返回null,个人觉得很不合理。稍微改了一下,增加了等待时间。另外,连接池的容量改成了缓慢增加,而不是一下子就翻一倍。
ConnectionPool.java
import java.io.FileInputStream; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import java.util.Vector; public class ConnectionPool { private Vector<Connection> pool; private String url; private String username; private String password; private String driverClassName; /** * 请求连接的等待时间限制 */ private long timeout; /** * 连接池的大小,也就是连接池中有多少个数据库连接。 */ private int poolSize; private int poolSizeMax; private static ConnectionPool instance = new ConnectionPool(); private ConnectionManager connectionManager; /** * 私有的构造方法,禁止外部创建本类的对象,要想获得本类的对象,通过<code>getIstance</code>方法。 * 使用了设计模式中的单子模式。 */ private ConnectionPool() { init(); } /** * 连接池初始化方法,读取属性文件的内容 建立连接池中的初始连接 */ private void init() { pool = new Vector<Connection>(); readConfig(); initConnection(poolSize); //初始化最小的线程数 connectionManager = new ConnectionManager(pool,poolSize); connectionManager.start(); } /** * 返回连接到连接池中 */ public synchronized void release(Connection conn) { pool.add(conn); notifyAll();//通知所有等待连接的线程 } /** * 关闭连接池中的所有数据库连接 */ public synchronized void closePool() { for (int i = 0; i < pool.size(); i++) { try { ((Connection) pool.get(i)).close(); } catch (SQLException e) { e.printStackTrace(); } pool.remove(i); } } /** * 返回当前连接池的一个对象 */ public static ConnectionPool getInstance() { return instance; } /** * 返回连接池中的一个数据库连接 */ public synchronized Connection getConnection() { Connection conn =null; try { conn = getConnection(timeout); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 返回连接池中的一个数据库连接 * @throws SQLException */ private Connection getConnection(long timeout) throws SQLException { long startTime = System.currentTimeMillis(); long remaining = timeout; Connection conn = null; while((conn=getPooledConnection()) == null){ try { wait(remaining);//没有可用的链接,线程等待,直到超时或其它线程调用了notifyAll } catch (InterruptedException e) { e.printStackTrace(); } remaining = timeout - (System.currentTimeMillis() - startTime); if(remaining<=0){ //超时则抛出异常 throw new SQLException("getConnection() timeout"); } } //如果无异常抛出,则获得了一个连接,现测试该连接是否可用 if(!isConnectionOK(conn)){ return getConnection(remaining); } return conn; } /** * 测试连接是否真正是可用的 */ private boolean isConnectionOK(Connection conn) { Statement stmt = null; try{ if(!conn.isClosed()){ stmt = conn.createStatement(); stmt.close(); } else{ return false; } } catch(SQLException e){ if(stmt!=null){ try{ stmt.close(); } catch(SQLException se){ } } return false; } return true; } /** * 在连接池中创建初始设置的的数据库连接 */ private void initConnection(int size) { Connection conn = null; for (int i = 0; i < size; i++) { try { Class.forName(driverClassName); conn = java.sql.DriverManager.getConnection(url, username, password); pool.add(conn); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } private Connection getPooledConnection(){ Connection conn = null; if(pool.size()>0){ conn = pool.remove(0); } else if(pool