Druid数据库连接池源码理解

重要参数解读

  • maxWait: 获取Connection的最大超时等待时间
  • poolingCount:线程池拥有的连接数量
  • activeCount: 活跃连接数量
  • maxActive: 最大连接池数量

获取连接的流程

  1. 先进行 init 操作
    • 创建DruidConnectionHolder数组connections
    • 根据initialSize生成真正的数据库连接,并且加入到connections数组
    • 调用createAndStartCreatorThread()方法,开启一个创建数据库连接的线程
  2. 调用getConnectionInternal()方法。先从连接池中取出 DruidConnectionHolder,然后再封装成DruidPooledConnection对象返回。

重要代码片段

init操作

connections = new DruidConnectionHolder[maxActive]; //定义 数组 
DruidConnectionHolder holder = new DruidConnectionHolder(this, pyConnectInfo); //将PhysicalConnectionInfo封装成DruidConnectionHolder
connections[poolingCount] = holder;//将DruidConnectionHolder放入connections数据组中

生成真正的数据库连接 Connect 并且封装成 PhysicalConnectionInfo

PhysicalConnectionInfo pyConnectInfo = createPhysicalConnection(); 

public Connection createPhysicalConnection(String url, Properties info) throws SQLException {
        Connection conn;
        if (getProxyFilters().size() == 0) {
        	//最核心代码
            conn = getDriver().connect(url, info);
        } else {
            conn = new FilterChainImpl(this).connection_connect(info);
        }

        createCount.incrementAndGet();

        return conn;
    }

用户名和密码如果有回调函数,那么从回调方法中获取 UserName或 Password,如果filters长度不为0,那么执行FilterChain操作。 filters使用这个方式定义:

protected List<Filter>   filters   = new CopyOnWriteArrayList<Filter>();

getConnectionInternal方法

protected Condition                                notEmpty;
protected Condition                                empty;
lock = new ReentrantLock(lockFair);

notEmpty = lock.newCondition();
empty = lock.newCondition();

if (maxWait > 0) {
    holder = pollLast(nanos);
} else {
    holder = takeLast();
}
DruidPooledConnection poolalbeConnection = new DruidPooledConnection(holder);// 持有所在线程等
return poolalbeConnection

连接池为空时释放信号操作emptySignal()


protected ScheduledExecutorService                 createScheduler;

CreateConnectionTask task = new CreateConnectionTask();
createScheduler.submit(task);

//CreateConnectionTask run 使用 lock.lock(); 方法
// 必须存在线程等待,才创建连接
//最后创建连接
physicalConnection = createPhysicalConnection(); 

recycle原理: 需要回收的连接,检查合格后把连接 holder 加入到 connections 数组中去,达到回收的效果

图解

在这里插入图片描述

涉及知识点

  • volatile 关键字使用
  • FilterChain设计模式
  • ReentrantLock、Condition、countDown的使用
  • AtomicInteger原子类使用
    获得数据源IddataSourceIdSeed使用
dataSourceIdSeed = new AtomicInteger(0);
dataSourceIdSeed.incrementAndGet(); 
  • CopyOnWriteArrayList 原子List类使用
  • ScheduledExecutorService线程池的使用

总结

Druid 数据库连接池使用了不少 JAVA高级操作,这些点都是需要单独去学习的,这样才能更好的掌握Druid。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值