日期:2014-05-16 浏览次数:20561 次
public class ConnectionPool { private static Logger logger = Logger.getLogger(ConnectionPool.class); //当前已用连接数 private static volatile int curConnections = 0; private static Config config = null; //初始化成功标志 private static boolean initFlag = false; private static volatile Stack<Connection> conns; static { PropertyReader pr = null; try { pr = new PropertyReader("pool-config.properties"); config = new Config(); //设置数据库驱动 config.setDriver(pr.getValue("driver")); //url config.setUrl(pr.getValue("url")); //uername config.setUsername(pr.getValue("username")); //password config.setPassword(pr.getValue("password")); //最大连接数 if(pr.getValue("maxConnections") != null){ config.setMaxConnections(Integer.valueOf(pr.getValue("maxConnections"))); } //初始化时最小连接数 if(pr.getValue("minConnections") != null){ config.setMinConnections(Integer.valueOf(pr.getValue("minConnections"))); } //返还连接时是否提交 if(pr.getValue("autoCommitOnClose") != null){ config.setAutoCommitOnClose(Boolean.valueOf(pr.getValue("autoCommitOnClose"))); } //当连接池用完时客户端调用getConn()后等待获取新连接的时间 //Default: (100毫秒) if(pr.getValue("checkoutTimeout") != null){ config.setCheckoutTimeout(Integer.valueOf(pr.getValue("checkoutTimeout"))); } //当没有可用链接时,尝试获取链接的次数 if(pr.getValue("checkTimes") != null){ config.setCheckTimes(Integer.valueOf(pr.getValue("checkTimes"))); } initPool(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } /** * 隐藏构造函数 */ private ConnectionPool(){ } /** * 初始化连接池 保存minConnections个链接 * @throws SQLException * @throws ClassNotFoundException */ private static synchronized void initPool() throws SQLException, ClassNotFoundException{ conns = new Stack<Connection>(); Class.forName(config.getDriver()); for(int i = 0 ; i < config.getMinConnections() ; i++){ Connection conn = newConnection(); conns.push(conn); } initFlag = true; } /** * 获取一个可用链接 * @return * @throws SQLException * @throws InterruptedException * @throws DBPoolException * @throws Exception */ public static Connection getConn() throws SQLException, InterruptedException, DBPoolException { Connection conn = null; if (initFlag) { synchronized (conns) { // 循环次数 int times = 0; while (null == conn && times < config.getCheckTimes() + 1) { times++; // 如果未达到最大链接 if (curConnections < config.getMaxConnections()) { // 栈中未空 if (!conns.isEmpty()) { conn = conns.pop(); // 如果返回的链接不可用 if (null == conn || conn.isClosed()) { conn = newConnection(); } // 栈中空了 } else { conn = newConnection(); } } else { conns.wait(config.getCheckoutTimeout()); } } if(null == conn){ logger.warn("获取链接超时!!!!!"); throw new DBPoolException("获取链接超时!!!!!"); }else{ curConnections++; conns.notifyAll(); } } } else { logger.error("连接池初始化失败!!!!"); throw new DBPoolException("连接池初始化失败!!!!"); } return conn; } /** * 归还一个链接 * @param conn * @throws SQLException * @throws InterruptedException */ public static void returnConn(Connection conn) throws SQLException, InterruptedException { synchronized (conns) { if (null != conn && !conn.isClosed()) { // 如果设置归还前自动提交为真 if (config.isAutoCommitOnClose()) { conn.commit(); } else { conn.rollback(); } } int times = 0; //尝试归还5次 如果归还失败则关闭连接 while (times < 6) { t