数据库连接池实现

1.定义数据库信息的bean


package jdbc.pool;
 
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() {
    }
 
    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 String getDriverName() {
        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 long getConnTimeOut() {
        return connTimeOut;
    }
 
    public void setConnTimeOut(long connTimeOut) {
        this.connTimeOut = connTimeOut;
    }
 
    public int getMaxActiveConnections() {
        return maxActiveConnections;
    }
 
    public void setMaxActiveConnections(int maxActiveConnections) {
        this.maxActiveConnections = maxActiveConnections;
    }
 
    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 boolean isCheakPool() {
        return isCheakPool;
    }
 
    public void setCheakPool(boolean isCheakPool) {
        this.isCheakPool = isCheakPool;
    }
 
    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;
    }
    
    
}

2.定义接口
package jdbc.pool;
 
import java.sql.Connection;
 
public interface IConnectionPool {
    //获得连接
    public Connection getConnection();
    //获得当前连接
    public Connection getCurrentConnection();
    //回收连接
    public void releaseConnection(Connection conn);
    //销毁清空
    public void destroy();
    //是否活动状态
    public boolean isActive();
    //定时器,检查连接池
    public void checkPool();
    
}


3.接口实现

package jdbc.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 List<Connection> freeConnection = new Vector<Connection>();
    // 活动连接
    private List<Connection> activeConnection = new Vector<Connection>();
    // 将线程和连接绑定,保证事务能统一执行
 
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
 
    /**
     * 
     */
    public ConnectionPool(DBbean dbBean) {
        super();
        this.dbBean = dbBean;
        init();
        checkPool();
    }
 
    // 初始化
    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();
        }
    }
 
    @Override
    // 获得连接
    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;
    }
 
    @Override
    // 获得当前连接
    public Connection getCurrentConnection() {
        // 默认线程里面取
        Connection conn = threadLocal.get();
        if (!isValid(conn)) {
            conn = getConnection();
        }
        return conn;
    }
 
    @Override
    // 释放连接
    public synchronized void releaseConnection(Connection conn) {
        if (isValid(conn) && !(freeConnection.size() > dbBean.getMaxConnections())) {
            freeConnection.add(conn);
            activeConnection.remove(conn);
            contActive--;
            threadLocal.remove();
            // 唤醒所有正待等待的线程,去抢连接
            notifyAll();
        }
    }
 
    @Override
    // 销毁连接池
    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 checkPool() {
        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());
        }
 
    }
 
    // 获得新连接
    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;
    }
 
    // 判断连接是否可用
    private boolean isValid(Connection conn) {
        try {
            if (conn == null || conn.isClosed()) {
                return false;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return true;
    }
}

4.管理连接
package jdbc.pool;
 
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
 
public class ConnectionPoolManager {
    
   // 连接池存放  
   public Hashtable<String,IConnectionPool> pools = new Hashtable<String, 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;i<DBInitInfo.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:Can't find this connecion pool ->"+poolName);  
       }  
       return conn;  
   }  
     
   // 关闭,回收连接  
   public void close(String poolName,Connection conn){  
           IConnectionPool pool = getPool(poolName);  
           if(pool != null){  
               pool.releaseConnection(conn);  
           }  
   }  
     
   // 清空连接池  
   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;  
   }  
}  
5.
package jdbc.pool;
 
import java.sql.Connection;
 
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.getCurrentConnection();  
        }  
        return conn;  
    }  
}  


6.这个类的信息,应该从配置文件读取
package jdbc.pool;
 
import java.util.ArrayList;
import java.util.List;
 
/** 
 * 初始化,模拟加载所有的配置文件 
 * @author Ran 
 * 
 */  
public class DBInitInfo {  
    public  static List<DBbean>  beans = null;  
    static{  
        beans = new ArrayList<DBbean>();  
        // 这里数据 可以从xml 等配置文件进行获取  
        // 为了测试,这里我直接写死  
        DBbean beanOracle = new DBbean();  
        beanOracle.setDriverName("xxx");  
        beanOracle.setUrl("xxx");  
        beanOracle.setUserName("xxx");  
        beanOracle.setPassword("xxx");  
          
        beanOracle.setMinConnections(5);  
        beanOracle.setMaxConnections(100);  
          
        beanOracle.setPoolName("testPool");  
        beans.add(beanOracle);  
    }  
}  

7.测试类
package jdbc.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");  
    }  
  

--------------------- 
转载:https://blog.csdn.net/HappyArthur/article/details/52263870 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值