jdbc 链接池的优化

package cn.itcast.jdbc.datasourse;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

public class MyDataSourse {
    private static String url = "jdbc:mysql://localhost:3306/test";
    private static String user = "root";
    private static String pwd = "";
    
    //用于存放链接
    private LinkedList<Connection> connectionsPool = new LinkedList<Connection>();
    
    /*当创建链接时,不是随意的我想创建多少个链接就创建多少个链接,这时因为数据库的链接是有限的
     * 当超过这个范围时,数据库是承受不了的,所以我们就要限制创建链接的个数*/
    private static int initCount = 5;     //设置最小链接数
    private static int maxCount = 20;     //设置最大链接数
    private int currentCount = 0;         //记录当前链接数
    
    
    //初始化链接池时,向链接池内放入10个链接   
    public MyDataSourse(){
        try {
            for(int i = 0;i< initCount ;i++){
                this.connectionsPool.addLast(this.createConnection());
                this.currentCount++;
            }
        } catch (SQLException e) {
//            e.printStackTrace();
            throw new ExceptionInInitializerError(e);
        }
    }
    //得到链接
    /*Connection是不支持多线程的,当有多个请求建立链接时,就要保证他们各自拿到的链接不相等
     * 这时就需要用到同步代码块*/
    public Connection getConnection() throws SQLException{
        synchronized(connectionsPool){      //这里的锁用的就是链接池
            if(this.connectionsPool.size() > 0){    //如果池里还有就直接取
                return this.connectionsPool.removeFirst();
            }
            if(this.currentCount < maxCount) {  //如果池里没有了,就判断当前链接是否超过最大链接数,如果没有就创建
                this.currentCount++;
                return this.createConnection();
            }
            /*如果说池里没有了,而且已经达到最大链接数这时有3种处理方式
             * 1 抛一个异常出去
             * 2 返回一个null
             * 3 让它等待别人释放链接
             * 这里简单的处理,抛一个异常出去
             * */
            throw new SQLException("已没有链接");
        }
    }
    
    //释放链接  如果用链接池的话,当我们要释放资源的时候就不能够简单的把conn给关闭掉,而应该是把conn重新放回到链接池中
    public void free(Connection conn){
        this.connectionsPool.addLast(conn);
    }
    //创建链接
    private Connection createConnection() throws SQLException{
        return DriverManager.getConnection(url,user,pwd);
    }
}
/*
 * 当我们对数据库进行操作时,往往花费在建立和数据库的链接时花费的时间最长,所以最好就是链接保证链接不要
 * 频繁的建立,这时就应该考虑到创建一个链接池,每次用的时候直接从链接池中去取,用完后再放回去
 * 这样做虽然在创建时花费的时间会很长,但是一旦创建完成,在用的时候就能够很好的提高效率
 * */

/*这种方法实际上还存在问题,原因是当调用着在执行完数据库的操作后没有用free方法去关闭链接,而是直接conn.close()将链接给关掉了,这样链接就不能重新放回到连接池中

这时就要考虑用代理的模式去修改代码,解决这个问题,让调用着在执行conn.close()方法时,实际上是将该链接放回到连接池中*/

原文地址:https://www.cnblogs.com/siashan/p/3881384.html