免费设计网站logo,代加工订单网,wordpress文件删除,徐州模板建站定制网站转载自 JAVA数据库连接池实现连接池的管理用了了享元模式#xff0c;这里对连接池进行简单设计。
一、设计思路1.连接池配置属性DBbean#xff1a;里面存放可以配置的一些属性2.连接池接口IConnectionPool#xff1a;里面定义一些基本的获取连接的一些方法3.接口实现Conne…转载自 JAVA数据库连接池实现连接池的管理用了了享元模式这里对连接池进行简单设计。
一、设计思路1.连接池配置属性DBbean里面存放可以配置的一些属性2.连接池接口IConnectionPool里面定义一些基本的获取连接的一些方法3.接口实现ConnectionPool对上面操作进行实现并加入一些其他方法4.连接池管理ConnectionPoolManager管理所有的不同的连接池所有的连接都能通过这里进行获得连接5.另外还有几个测试类和连接信息模拟的类这里就不进行xml 和配置文件信息的读取了
package pool; /** * 这是外部可以配置的连接池属性 * 可以允许外部配置拥有默认值 * author Ran * */ public class DBbean { // 连接池属性 private String driverName; private String url; private String userName; private String password; // 连接池名字 private String poolName; private int minConnections 1; // 空闲池最小连接数 private int maxConnections 10; // 空闲池最大连接数 private int initConnections 5;// 初始化连接数 private long connTimeOut 1000;// 重复获得连接的频率 private int maxActiveConnections 100;// 最大允许的连接数和数据库对应 private long connectionTimeOut 1000*60*20;// 连接超时时间默认20分钟 private boolean isCurrentConnection true; // 是否获得当前连接默认true private boolean isCheakPool true; // 是否定时检查连接池 private long lazyCheck 1000*60*60;// 延迟多少时间后开始 检查 private long periodCheck 1000*60*60;// 检查频率 public DBbean(String driverName, String url, String userName, String password, String poolName) { super(); this.driverName driverName; this.url url; this.userName userName; this.password password; this.poolName poolName; } public DBbean() { } public String getDriverName() { if(driverName null){ driverName this.getDriverName()_this.getUrl(); } return driverName; } public void setDriverName(String driverName) { this.driverName driverName; } public String getUrl() { return url; } public void setUrl(String url) { this.url url; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password password; } public String getPoolName() { return poolName; } public void setPoolName(String poolName) { this.poolName poolName; } public int getMinConnections() { return minConnections; } public void setMinConnections(int minConnections) { this.minConnections minConnections; } public int getMaxConnections() { return maxConnections; } public void setMaxConnections(int maxConnections) { this.maxConnections maxConnections; } public int getInitConnections() { return initConnections; } public void setInitConnections(int initConnections) { this.initConnections initConnections; } public int getMaxActiveConnections() { return maxActiveConnections; } public void setMaxActiveConnections(int maxActiveConnections) { this.maxActiveConnections maxActiveConnections; } public long getConnTimeOut() { return connTimeOut; } public void setConnTimeOut(long connTimeOut) { this.connTimeOut connTimeOut; } public long getConnectionTimeOut() { return connectionTimeOut; } public void setConnectionTimeOut(long connectionTimeOut) { this.connectionTimeOut connectionTimeOut; } public boolean isCurrentConnection() { return isCurrentConnection; } public void setCurrentConnection(boolean isCurrentConnection) { this.isCurrentConnection isCurrentConnection; } public long getLazyCheck() { return lazyCheck; } public void setLazyCheck(long lazyCheck) { this.lazyCheck lazyCheck; } public long getPeriodCheck() { return periodCheck; } public void setPeriodCheck(long periodCheck) { this.periodCheck periodCheck; } public boolean isCheakPool() { return isCheakPool; } public void setCheakPool(boolean isCheakPool) { this.isCheakPool isCheakPool; } } Java代码 package pool; import java.sql.Connection; import java.sql.SQLException; public interface IConnectionPool { // 获得连接 public Connection getConnection(); // 获得当前连接 public Connection getCurrentConnecton(); // 回收连接 public void releaseConn(Connection conn) throws SQLException; // 销毁清空 public void destroy(); // 连接池是活动状态 public boolean isActive(); // 定时器检查连接池 public void cheackPool(); } package pool; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.Vector; public class ConnectionPool implements IConnectionPool { // 连接池配置属性 private DBbean dbBean; private boolean isActive false; // 连接池活动状态 private int contActive 0;// 记录创建的总的连接数 // 空闲连接 private ListConnection freeConnection new VectorConnection(); // 活动连接 private ListConnection activeConnection new VectorConnection(); // 将线程和连接绑定保证事务能统一执行 private static ThreadLocalConnection threadLocal new ThreadLocalConnection(); public ConnectionPool(DBbean dbBean) { super(); this.dbBean dbBean; init(); cheackPool(); } // 初始化 public void init() { try { Class.forName(dbBean.getDriverName()); for (int i 0; i dbBean.getInitConnections(); i) { Connection conn; conn newConnection(); // 初始化最小连接数 if (conn ! null) { freeConnection.add(conn); contActive; } } isActive true; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } // 获得当前连接 public Connection getCurrentConnecton(){ // 默认线程里面取 Connection conn threadLocal.get(); if(!isValid(conn)){ conn getConnection(); } return conn; } // 获得连接 public synchronized Connection getConnection() { Connection conn null; try { // 判断是否超过最大连接数限制 if(contActive this.dbBean.getMaxActiveConnections()){ if (freeConnection.size() 0) { conn freeConnection.get(0); if (conn ! null) { threadLocal.set(conn); } freeConnection.remove(0); } else { conn newConnection(); } }else{ // 继续获得连接,直到从新获得连接 wait(this.dbBean.getConnTimeOut()); conn getConnection(); } if (isValid(conn)) { activeConnection.add(conn); contActive ; } } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return conn; } // 获得新连接 private synchronized Connection newConnection() throws ClassNotFoundException, SQLException { Connection conn null; if (dbBean ! null) { Class.forName(dbBean.getDriverName()); conn DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(), dbBean.getPassword()); } return conn; } // 释放连接 public synchronized void releaseConn(Connection conn) throws SQLException { if (isValid(conn) !(freeConnection.size() dbBean.getMaxConnections())) { freeConnection.add(conn); activeConnection.remove(conn); contActive --; threadLocal.remove(); // 唤醒所有正待等待的线程去抢连接 notifyAll(); } } // 判断连接是否可用 private boolean isValid(Connection conn) { try { if (conn null || conn.isClosed()) { return false; } } catch (SQLException e) { e.printStackTrace(); } return true; } // 销毁连接池 public synchronized void destroy() { for (Connection conn : freeConnection) { try { if (isValid(conn)) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } for (Connection conn : activeConnection) { try { if (isValid(conn)) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } isActive false; contActive 0; } // 连接池状态 Override public boolean isActive() { return isActive; } // 定时检查连接池情况 Override public void cheackPool() { if(dbBean.isCheakPool()){ new Timer().schedule(new TimerTask() { Override public void run() { // 1.对线程里面的连接状态 // 2.连接池最小 最大连接数 // 3.其他状态进行检查因为这里还需要写几个线程管理的类暂时就不添加了 System.out.println(空线池连接数freeConnection.size()); System.out.println(活动连接数activeConnection.size()); System.out.println(总的连接数contActive); } },dbBean.getLazyCheck(),dbBean.getPeriodCheck()); } } } package pool; import java.sql.Connection; import java.sql.SQLException; import java.util.Hashtable; /** * 连接管理类 * author Ran * */ public class ConnectionPoolManager { // 连接池存放 public HashtableString,IConnectionPool pools new HashtableString, IConnectionPool(); // 初始化 private ConnectionPoolManager(){ init(); } // 单例实现 public static ConnectionPoolManager getInstance(){ return Singtonle.instance; } private static class Singtonle { private static ConnectionPoolManager instance new ConnectionPoolManager(); } // 初始化所有的连接池 public void init(){ for(int i 0;iDBInitInfo.beans.size();i){ DBbean bean DBInitInfo.beans.get(i); ConnectionPool pool new ConnectionPool(bean); if(pool ! null){ pools.put(bean.getPoolName(), pool); System.out.println(Info:Init connection successed - bean.getPoolName()); } } } // 获得连接,根据连接池名字 获得连接 public Connection getConnection(String poolName){ Connection conn null; if(pools.size()0 pools.containsKey(poolName)){ conn getPool(poolName).getConnection(); }else{ System.out.println(Error:Cant find this connecion pool -poolName); } return conn; } // 关闭回收连接 public void close(String poolName,Connection conn){ IConnectionPool pool getPool(poolName); try { if(pool ! null){ pool.releaseConn(conn); } } catch (SQLException e) { System.out.println(连接池已经销毁); e.printStackTrace(); } } // 清空连接池 public void destroy(String poolName){ IConnectionPool pool getPool(poolName); if(pool ! null){ pool.destroy(); } } // 获得连接池 public IConnectionPool getPool(String poolName){ IConnectionPool pool null; if(pools.size() 0){ pool pools.get(poolName); } return pool; } } package pool; import java.util.ArrayList; import java.util.List; /** * 初始化模拟加载所有的配置文件 * author Ran * */ public class DBInitInfo { public static ListDBbean beans null; static{ beans new ArrayListDBbean(); // 这里数据 可以从xml 等配置文件进行获取 // 为了测试这里我直接写死 DBbean beanOracle new DBbean(); beanOracle.setDriverName(oracle.jdbc.driver.OracleDriver); beanOracle.setUrl(jdbc:oracle:thin:7MEXGLUY95W1Y56:1521:orcl); beanOracle.setUserName(mmsoa); beanOracle.setPassword(password1234); beanOracle.setMinConnections(5); beanOracle.setMaxConnections(100); beanOracle.setPoolName(testPool); beans.add(beanOracle); } } 测试
package pool; import java.sql.Connection; /** * 模拟线程启动去获得连接 * author Ran * */ public class ThreadConnection implements Runnable{ private IConnectionPool pool; Override public void run() { pool ConnectionPoolManager.getInstance().getPool(testPool); } public Connection getConnection(){ Connection conn null; if(pool ! null pool.isActive()){ conn pool.getConnection(); } return conn; } public Connection getCurrentConnection(){ Connection conn null; if(pool ! null pool.isActive()){ conn pool.getCurrentConnecton(); } return conn; } } package pool; public class Client { public static void main(String[] args) throws InterruptedException { // 初始化连接池 Thread t init(); t.start(); t.join(); ThreadConnection a new ThreadConnection(); ThreadConnection b new ThreadConnection(); ThreadConnection c new ThreadConnection(); Thread t1 new Thread(a); Thread t2 new Thread(b); Thread t3 new Thread(c); // 设置优先级先让初始化执行模拟 线程池 先启动 // 这里仅仅表面控制了因为即使t 线程先启动也不能保证pool 初始化完成为了简单模拟这里先这样写了 t1.setPriority(10); t2.setPriority(10); t3.setPriority(10); t1.start(); t2.start(); t3.start(); System.out.println(线程A- a.getConnection()); System.out.println(线程B- b.getConnection()); System.out.println(线程C- c.getConnection()); } // 初始化 public static Thread init() { Thread t new Thread(new Runnable() { Override public void run() { IConnectionPool pool initPool(); while(pool null || !pool.isActive()){ pool initPool(); } } }); return t; } public static IConnectionPool initPool(){ return ConnectionPoolManager.getInstance().getPool(testPool); } } 小结 1.连接池诞生原因是如果每次都从数据库获得连接时间比较长因此我们提前做建立一些连接放在连接池里面每次都从里面取2.上面仅仅写了连接池基本原理关于多线程下连接池的管理没写后面对多线程操作熟练了添加吧