多线程情况下创建连接池

来源:互联网 发布:懒人听书 源码 编辑:程序博客网 时间:2024/06/05 15:25

JAVA数据库连接池实现
博客分类:
• 数据库连接池
JAVA数据库连接池连接池原理连接池实现JAVA连接池
连接池的管理用了了享元模式,这里对连接池进行简单设计。
一、设计思路
1.连接池配置属性DBbean:里面存放可以配置的一些属性
2.连接池接口IConnectionPool:里面定义一些基本的获取连接的一些方法
3.接口实现ConnectionPool:对上面操作进行实现,并加入一些其他方法
4.连接池管理ConnectionPoolManager:管理所有的不同的连接池,所有的连接都能通过这里进行获得连接
5.另外还有几个测试类,和连接信息模拟的类,这里就不进行xml 和配置文件信息的读取了
Java代码

1.  package pool;  2.  /** 3.   * 这是外部可以配置的连接池属性 4.   * 可以允许外部配置,拥有默认值 5.   * @author Ran 6.   * 7.   */  8.  public class DBbean {  9.      // 连接池属性  10.     private String driverName;  11.     private String url;  12.     private String userName;  13.     private String password;  14.     // 连接池名字  15.     private String poolName;  16.     private int minConnections = 1; // 空闲池,最小连接数  17.     private int maxConnections = 10; // 空闲池,最大连接数  18.       19.     private int initConnections = 5;// 初始化连接数  20.       21.     private long connTimeOut = 1000;// 重复获得连接的频率  22.       23.     private int maxActiveConnections = 100;// 最大允许的连接数,和数据库对应  24.       25.     private long connectionTimeOut = 1000*60*20;// 连接超时时间,默认20分钟  26.       27.     private boolean isCurrentConnection = true; // 是否获得当前连接,默认true  28.       29.     private boolean isCheakPool = true; // 是否定时检查连接池  30.     private long lazyCheck = 1000*60*60;// 延迟多少时间后开始 检查  31.     private long periodCheck = 1000*60*60;// 检查频率  32.       33.       34.       35.     public DBbean(String driverName, String url, String userName,  36.             String password, String poolName) {  37.         super();  38.         this.driverName = driverName;  39.         this.url = url;  40.         this.userName = userName;  41.         this.password = password;  42.         this.poolName = poolName;  43.     }  44.     public DBbean() {  45.     }  46.     public String getDriverName() {  47.         if(driverName == null){  48.             driverName = this.getDriverName()+"_"+this.getUrl();  49.         }  50.         return driverName;  51.     }  52.     public void setDriverName(String driverName) {  53.         this.driverName = driverName;  54.     }  55.     public String getUrl() {  56.         return url;  57.     }  58.     public void setUrl(String url) {  59.         this.url = url;  60.     }  61.     public String getUserName() {  62.         return userName;  63.     }  64.     public void setUserName(String userName) {  65.         this.userName = userName;  66.     }  67.     public String getPassword() {  68.         return password;  69.     }  70.     public void setPassword(String password) {  71.         this.password = password;  72.     }  73.     public String getPoolName() {  74.         return poolName;  75.     }  76.     public void setPoolName(String poolName) {  77.         this.poolName = poolName;  78.     }  79.     public int getMinConnections() {  80.         return minConnections;  81.     }  82.     public void setMinConnections(int minConnections) {  83.         this.minConnections = minConnections;  84.     }  85.     public int getMaxConnections() {  86.         return maxConnections;  87.     }  88.     public void setMaxConnections(int maxConnections) {  89.         this.maxConnections = maxConnections;  90.     }  91.     public int getInitConnections() {  92.         return initConnections;  93.     }  94.     public void setInitConnections(int initConnections) {  95.         this.initConnections = initConnections;  96.     }  97.   98.     public int getMaxActiveConnections() {  99.         return maxActiveConnections;  100.        }  101.        public void setMaxActiveConnections(int maxActiveConnections) {  102.            this.maxActiveConnections = maxActiveConnections;  103.        }  104.        public long getConnTimeOut() {  105.            return connTimeOut;  106.        }  107.        public void setConnTimeOut(long connTimeOut) {  108.            this.connTimeOut = connTimeOut;  109.        }  110.        public long getConnectionTimeOut() {  111.            return connectionTimeOut;  112.        }  113.        public void setConnectionTimeOut(long connectionTimeOut) {  114.            this.connectionTimeOut = connectionTimeOut;  115.        }  116.        public boolean isCurrentConnection() {  117.            return isCurrentConnection;  118.        }  119.        public void setCurrentConnection(boolean isCurrentConnection) {  120.            this.isCurrentConnection = isCurrentConnection;  121.        }  122.        public long getLazyCheck() {  123.            return lazyCheck;  124.        }  125.        public void setLazyCheck(long lazyCheck) {  126.            this.lazyCheck = lazyCheck;  127.        }  128.        public long getPeriodCheck() {  129.            return periodCheck;  130.        }  131.        public void setPeriodCheck(long periodCheck) {  132.            this.periodCheck = periodCheck;  133.        }  134.        public boolean isCheakPool() {  135.            return isCheakPool;  136.        }  137.        public void setCheakPool(boolean isCheakPool) {  138.            this.isCheakPool = isCheakPool;  139.        }  140.          141.          142.          143.    }  

Java代码

1.  package pool;  2.    3.  import java.sql.Connection;  4.  import java.sql.SQLException;  5.    6.  public interface IConnectionPool {  7.      // 获得连接  8.      public Connection  getConnection();  9.      // 获得当前连接  10.     public Connection getCurrentConnecton();  11.     // 回收连接  12.     public void releaseConn(Connection conn) throws SQLException;  13.     // 销毁清空  14.     public void destroy();  15.     // 连接池是活动状态  16.     public boolean isActive();  17.     // 定时器,检查连接池  18.     public void cheackPool();  19. }  

Java代码

1.  package pool;  2.    3.  import java.sql.Connection;  4.  import java.sql.DriverManager;  5.  import java.sql.SQLException;  6.  import java.util.List;  7.  import java.util.Timer;  8.  import java.util.TimerTask;  9.  import java.util.Vector;  10.   11. public class ConnectionPool implements IConnectionPool {  12.     // 连接池配置属性  13.     private DBbean dbBean;  14.     private boolean isActive = false; // 连接池活动状态  15.     private int contActive = 0;// 记录创建的总的连接数  16.       17.     // 空闲连接  18.     private List<Connection> freeConnection = new Vector<Connection>();  19.     // 活动连接  20.     private List<Connection> activeConnection = new Vector<Connection>();  21.     // 将线程和连接绑定,保证事务能统一执行  22.     private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();  23.       24.     public ConnectionPool(DBbean dbBean) {  25.         super();  26.         this.dbBean = dbBean;  27.         init();  28.         cheackPool();  29.     }  30.   31.     // 初始化  32.     public void init() {  33.         try {  34.             Class.forName(dbBean.getDriverName());  35.             for (int i = 0; i < dbBean.getInitConnections(); i++) {  36.                 Connection conn;  37.                 conn = newConnection();  38.                 // 初始化最小连接数  39.                 if (conn != null) {  40.                     freeConnection.add(conn);  41.                     contActive++;  42.                 }  43.             }  44.             isActive = true;  45.         } catch (ClassNotFoundException e) {  46.             e.printStackTrace();  47.         } catch (SQLException e) {  48.             e.printStackTrace();  49.         }  50.     }  51.       52.     // 获得当前连接  53.     public Connection getCurrentConnecton(){  54.         // 默认线程里面取  55.         Connection conn = threadLocal.get();  56.         if(!isValid(conn)){  57.             conn = getConnection();  58.         }  59.         return conn;  60.     }  61.   62.     // 获得连接  63.     public synchronized Connection getConnection() {  64.         Connection conn = null;  65.         try {  66.             // 判断是否超过最大连接数限制  67.             if(contActive < this.dbBean.getMaxActiveConnections()){  68.                 if (freeConnection.size() > 0) {  69.                     conn = freeConnection.get(0);  70.                     if (conn != null) {  71.                         threadLocal.set(conn);  72.                     }  73.                     freeConnection.remove(0);  74.                 } else {  75.                     conn = newConnection();  76.                 }  77.                   78.             }else{  79.                 // 继续获得连接,直到从新获得连接  80.                 wait(this.dbBean.getConnTimeOut());  81.                 conn = getConnection();  82.             }  83.             if (isValid(conn)) {  84.                 activeConnection.add(conn);  85.                 contActive ++;  86.             }  87.         } catch (SQLException e) {  88.             e.printStackTrace();  89.         } catch (ClassNotFoundException e) {  90.             e.printStackTrace();  91.         } catch (InterruptedException e) {  92.             e.printStackTrace();  93.         }  94.         return conn;  95.     }  96.   97.     // 获得新连接  98.     private synchronized Connection newConnection()  99.             throws ClassNotFoundException, SQLException {  100.            Connection conn = null;  101.            if (dbBean != null) {  102.                Class.forName(dbBean.getDriverName());  103.                conn = DriverManager.getConnection(dbBean.getUrl(),  104.                        dbBean.getUserName(), dbBean.getPassword());  105.            }  106.            return conn;  107.        }  108.      109.        // 释放连接  110.        public synchronized void releaseConn(Connection conn) throws SQLException {  111.            if (isValid(conn)&& !(freeConnection.size() > dbBean.getMaxConnections())) {  112.                freeConnection.add(conn);  113.                activeConnection.remove(conn);  114.                contActive --;  115.                threadLocal.remove();  116.                // 唤醒所有正待等待的线程,去抢连接  117.                notifyAll();  118.            }  119.        }  120.      121.        // 判断连接是否可用  122.        private boolean isValid(Connection conn) {  123.            try {  124.                if (conn == null || conn.isClosed()) {  125.                    return false;  126.                }  127.            } catch (SQLException e) {  128.                e.printStackTrace();  129.            }  130.            return true;  131.        }  132.      133.        // 销毁连接池  134.        public synchronized void destroy() {  135.            for (Connection conn : freeConnection) {  136.                try {  137.                    if (isValid(conn)) {  138.                        conn.close();  139.                    }  140.                } catch (SQLException e) {  141.                    e.printStackTrace();  142.                }  143.            }  144.            for (Connection conn : activeConnection) {  145.                try {  146.                    if (isValid(conn)) {  147.                        conn.close();  148.                    }  149.                } catch (SQLException e) {  150.                    e.printStackTrace();  151.                }  152.            }  153.            isActive = false;  154.            contActive = 0;  155.        }  156.      157.        // 连接池状态  158.        @Override  159.        public boolean isActive() {  160.            return isActive;  161.        }  162.          163.        // 定时检查连接池情况  164.        @Override  165.        public void cheackPool() {  166.            if(dbBean.isCheakPool()){  167.                new Timer().schedule(new TimerTask() {  168.                @Override  169.                public void run() {  170.                // 1.对线程里面的连接状态  171.                // 2.连接池最小 最大连接数  172.                // 3.其他状态进行检查,因为这里还需要写几个线程管理的类,暂时就不添加了  173.                System.out.println("空线池连接数:"+freeConnection.size());  174.                System.out.println("活动连接数::"+activeConnection.size());  175.                System.out.println("总的连接数:"+contActive);  176.                    }  177.                },dbBean.getLazyCheck(),dbBean.getPeriodCheck());  178.            }  179.        }  180.    }  

Java代码
1. package pool;
2.
3. import java.sql.Connection;
4. import java.sql.SQLException;
5. import java.util.Hashtable;
6. /**
7. * 连接管理类
8. * @author Ran
9. *
10. */
11. public class ConnectionPoolManager {
12.
13.
14. // 连接池存放
15. public Hashtable

1.  package pool;  2.    3.  import java.sql.Connection;  4.  /** 5.   * 模拟线程启动,去获得连接 6.   * @author Ran 7.   * 8.   */  9.  public class ThreadConnection implements Runnable{  10.     private IConnectionPool pool;  11.     @Override  12.     public void run() {  13.         pool = ConnectionPoolManager.getInstance().getPool("testPool");  14.     }  15.       16.     public Connection getConnection(){  17.         Connection conn = null;  18.         if(pool != null && pool.isActive()){  19.             conn = pool.getConnection();  20.         }  21.         return conn;  22.     }  23.       24.     public Connection getCurrentConnection(){  25.         Connection conn = null;  26.         if(pool != null && pool.isActive()){  27.             conn = pool.getCurrentConnecton();  28.         }  29.         return conn;  30.     }  31. }  

Java代码

1.  package pool;    5.  public class Client {  6.      public static void main(String[] args) throws InterruptedException {  7.          // 初始化连接池  8.          Thread t = init();  9.          t.start();  10.         t.join();  11.           12.         ThreadConnection a = new ThreadConnection();  13.         ThreadConnection b = new ThreadConnection();  14.         ThreadConnection c = new ThreadConnection();  15.         Thread t1 = new Thread(a);  16.         Thread t2 = new Thread(b);  17.         Thread t3 = new Thread(c);  18.           19.           20.         // 设置优先级,先让初始化执行,模拟 线程池 先启动  21.         // 这里仅仅表面控制了,因为即使t 线程先启动,也不能保证pool 初始化完成,为了简单模拟,这里先这样写了  22.         t1.setPriority(10);  23.         t2.setPriority(10);  24.         t3.setPriority(10);  25.         t1.start();  26.         t2.start();  27.         t3.start();  28.           29.         System.out.println("线程A-> "+a.getConnection());  30.         System.out.println("线程B-> "+b.getConnection());  31.         System.out.println("线程C-> "+c.getConnection());  32.     }  33.   34.     // 初始化  35.     public static Thread init() {  36.         Thread t = new Thread(new Runnable() {  37.             @Override  38.             public void run() {  39.                 IConnectionPool  pool = initPool();  40.                 while(pool == null || !pool.isActive()){  41.                     pool = initPool();  42.                 }  43.             }  44.         });  45.         return t;  46.     }  47.       48.     public static IConnectionPool initPool(){  49.         return ConnectionPoolManager.getInstance().getPool("testPool");  50.     }  51.   52. }  

小结 :
1.连接池诞生原因是,如果每次都从数据库获得连接,时间比较长,因此我们提前做建立一些连接,放在连接池里面,每次都从里面取
2.上面仅仅写了连接池基本原理,关于多线程下连接池的管理没写,后面对多线程操作熟练了添加吧

1 0
原创粉丝点击