1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > jsp获取连接池的实时连接数_数据库连接池原理分析及模拟实现

jsp获取连接池的实时连接数_数据库连接池原理分析及模拟实现

时间:2021-11-14 22:21:51

相关推荐

jsp获取连接池的实时连接数_数据库连接池原理分析及模拟实现

数据库访问

访问数据库主要有以下几个步骤:

加载数据库驱动创建数据库连接执行访问操作并处理执行结果关闭连接,释放资源

在每一次请求数据库都要经历上述过程,创建连接和释放资源也都是些重复性的动作,当请求量比较大时,资源是个很大的浪费。如何优化呢,可以使用连接池。

连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。

原理分析

数据库连接是访问数据库必须的,可以在系统初始化时提前创建一定数量的连接,保存起来,当有创建连接的请求过来时,就直接拿出来,标记为使用中(避免与其他请求拿到同一个),使用完后,再放回连接池中。过程如下

系统在启动时初始化连接池;向连接池请求可用的数据库连接;如果没有获取到可用的数据库连接,并且连接池中连接的数量小于最大连接数,则按照规定的步长给连接池中添加连接,然后再获取,如果连接池中的数量已经到了最大连接数还没有获取到可用的连接,则等待其他请求释放了连接后再获取;使用获取到的数据库连接请求数据库;将数据库连接放回连接池,供其他连接使用;

简单模拟实现

/** * 连接池对象 */public class Pool { private String driver = null;//数据库驱动 private String url = null;//连接地址 private String username = null;//用户 private String password = null;//密码 //初始化连接数 private static int initSize = 2; //池中最大连接数 private static int maxSize = 5; //每次创建的连接数 private static int stepSize = 2; //超时时间 private static int timeout = 2000; //用来保存创建的数据库连接 private List connectionPool = new ArrayList(); private Lock lock = new ReentrantLock(); public Pool(String driver, String url, String username, String password) throws Exception { this.driver = driver; this.url = url; this.username = username; this.password = password; //创建连接池时初始化initSize个数据库连接放入池中 resizePool(initSize); } /** * 初始化连接池 * @param num 初始时按照initSize给池中添加连接,其他时候按照stepSize给池中加 */ private void resizePool(int num) throws Exception { //池中现有的连接数 int currentNum = connectionPool.size(); //池中的连接数不能超过设置的最大连接数 if (maxSize < currentNum + num) { num = maxSize - currentNum; } //创建连接放入池中 for(int i=0; i 0){ //获取一个空闲的数据库连接 conn = getFreeConnFromPool(); //没有获取到连接 while(conn == null){ //隔2秒 重新获取 System.out.println(Thread.currentThread().getName() + " 等待获取连接"); Thread.sleep(2000); conn = getFreeConnFromPool(); } } return conn; } /** * 从连接池中获取空闲的连接 * @return */ private Connection getFreeConnFromPool() throws Exception { Connection conn = null; //获取可用的连接 conn = findAvailableConn(); //没有获取到可用的连接 if(conn == null){ //重新添加数据库连接到连接池中 resizePool(stepSize); //获取可用的连接 conn = findAvailableConn(); } return conn; } /** * 获取一个可用的连接 * @return * @throws Exception */ private Connection findAvailableConn() throws Exception { Connection conn = null; if(connectionPool.size() > 0){ for(PooledConnection cip : connectionPool){ if(!cip.isBusy()){ conn = cip.getConn(); cip.setBusy(true);//获取后将当前连接状态标记为 执行 //判断当前连接是否可用 if(!conn.isValid(timeout)){ //conn.isValid如果连接未关闭且有效,则返回true //当前连接池连接的数据库连接有问题,创建一个新的数据库连接代替它 conn = createConnection(); cip.setConn(conn); } break; } } } return conn; } /** * 把连接返回连接池 * 把连接返回给连接池就是把状态标记为‘闲’,可以让其他请求使用 */ public void returnConnToPool(Connection conn){ for (PooledConnection cip : connectionPool) { if (cip.getConn() == conn) { cip.setBusy(false);//设置为空闲 System.out.println(Thread.currentThread().getName() + " 释放了连接"); break; } } }}/** * 连接池中的连接对象 */public class PooledConnection { //数据库连接 private Connection conn; //用于标识当前数据库连接的状态 true:执行 false:空闲 private boolean busy; public PooledConnection(Connection conn) { this.conn = conn; } // 此处省略get set方法}

测试

public class App { public static void main(String[] args) throws Exception { //创建一个连接池 Pool pool = new Pool("com.mysql.jdbc.Driver

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。