对数据库连接池的一些修改
上次写的连接池一旦得不到连接就返回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(poolSize<poolSizeMax){ conn = newConnection(); }return conn; } /** * 获得新连接 */ private Connection newConnection(){ Connection conn = null ; try { Class.forName(driverClassName); conn = java.sql.DriverManager.getConnection(url, username, password); pool.add(conn); poolSize++; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 读取设置连接池的属性文件 */ private void readConfig() { try { String path = System.getProperty("user.dir") + "\\dbpool.properties"; FileInputStream is = new FileInputStream(path); Properties props = new Properties(); props.load(is); this.driverClassName = props.getProperty("driverClassName"); this.username = props.getProperty("username"); this.password = props.getProperty("password"); this.url = props.getProperty("url"); this.poolSize = Integer.parseInt(props.getProperty("poolSizeMin")); this.poolSizeMax = Integer.parseInt(props.getProperty("poolSizeMax")); this.timeout = Integer.parseInt(props.getProperty("timeout")); } catch (Exception e) { e.printStackTrace(); System.err.println("读取属性文件出错. "); } }}
?ConnectionManager.java
import java.sql.Connection;import java.util.Vector;public class ConnectionManager extends Thread{/*连接池最小的链接数量*/public static int MIN_SIZE = 3; private Vector<Connection> pool; private int poolSize;public ConnectionManager(Vector<Connection> pool,int poolSize){this.pool = pool;this.poolSize = poolSize;}public void run() {while(pool.size()>MIN_SIZE) {pool.setSize(pool.size()-1);poolSize--;try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}
?
dbpool.properties
driverClassName=com.microsoft.jdbc.sqlserver.SQLServerDriverusername=sapassword=123456url=jdbc:microsoft:sqlserver://localhost:1433/estorepoolSizeMax=10poolSizeMin=3timeout=5000
?
1 楼 wh8766 2009-03-08 一个小问题~