简单的数据库连接池写法及要点

在和数据库连接方面,大多数应用,都已经不再是需要一次就连接一次,而大多是通过数据库连接池来实现的。

因为数据库连接和销毁消耗性能是很大的,再一个,在一次数据库连接中,你可以做很多次查询或者维护工作,而不仅仅一次。

所以大多数情况下,数据库连接池使我们的首选。

这里主要讲述一个简单的数据库连接示例,其中使用等待超时来构造,在示例中模拟从连接池中获取、使用和释放连接的过程,而

客户端获取连接的过程被设定为等待超时的模式,也就是在一定时间内如果无法获取到可用连接,将会返回客户端一个null。

首先来看一下数据库连接池的定义。他通过构造函数初始化连接的最大上限,通过一个双向队列来维护连接,调用方需要调用fetchConnection(long)

方法来指定多少毫秒内超时获取连接,而releaseConnection(Connection)方法将连接放回池中。

示例代码:

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

/**
 * 我开始印象中是,数据库连接池,既会管理在池中空闲的,也会管理正在使用的,
 * 维护一个状态,事实证明,如果是这样,那代码维护将会变得十分困难。
 */
public class ConnectionPool {
	//一个双向数据库连接队列
    private LinkedList<Connection> pool = new LinkedList<Connection>();

    /**
     * 构造方法,初始化数据库连接池
     * @param initialSize
     */
    public ConnectionPool(int initialSize) {
        if (initialSize > 0) {
            for (int i = 0; i < initialSize; i++) {
                pool.addLast(ConnectionDriver.createConnection());
            }
        }
    }

    /**
     * 释放连接,即将connection放回池中,并且告知因阻塞而等待的连接请求队列。
     * @param connection
     */
    public void releaseConnection(Connection connection) {
        if (connection != null) {
            synchronized (pool) {
                // 添加后需要进行通知,这样其他消费者能够感知到链接池中已经归还了一个链接
                pool.addLast(connection);  //队尾入队
                pool.notifyAll();
            }
        }
    }

    // 在mills内无法获取到连接,将会返回null
    public Connection fetchConnection(long mills) throws InterruptedException {
        synchronized (pool) {
            // 完全超时
            if (mills <= 0) {
                while (pool.isEmpty()) {    //池中无连接可用,则进入阻塞状态。
                    pool.wait();
                }
                //队头出队
                return pool.removeFirst();
            } else {
                long future = System.currentTimeMillis() + mills;
                long remaining = mills;
                while (pool.isEmpty() && remaining > 0) {
                    pool.wait(remaining);
                    remaining = future - System.currentTimeMillis();
                }
                //如果超时,且仍无可用连接,则返回的result将为null
                Connection result = null;
                if (!pool.isEmpty()) {
                    result = pool.removeFirst();
                }
                return result;
            }
        }
    }
}


具体的说明都在代码注释中了,思想还是不难理解的,一条队列,队列仅仅维护可用的连接,而每个连接无用时,

则由工作线程将其重新放入数据库连接池中。

并且要注意同步,因为可能多个线程同时请求,此时就应该在同步块中进行代码实现。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值