Druid源码阅读系列(三)

今天来看下DruidDataSourceinit()方法剩下的线程创建部分代码,本来说第二天看的,拖到了第三天哈哈。。。

代码解读

这块其实是这个init()代码最关键的部分,因为涉及到连接的创建还有各种active count,pool count,minIdle count,maxActive等数量的计算和判断逻辑,当然里面还有一些更细化的维度,比如poolingPeak等,还有一些常用的配置参数会在这里面进行初始化,产生作用。

在这里插入图片描述

如上图经过前面校验后,会开始进行连接的创建,根据传入的CreateSchedulerAsyncInit值决定是异步创建还是同步创建。

首先看下异步创建,直接创建initialSize个数的连接,其主要实现是在CreateConnectionTask这个线程的runInternal()方法里,核心代码如下:

在这里插入图片描述

当有等待线程时,判断边界条件,poolingCount >= notEmptyWaitThreadCount注意这里的poolingCount不是指连接池连接上限,而是当前空闲连接数,这个我一开始理解错了, 连接池上限是poolingPeak这个,用activeCount + poolingCount < minIdle而不是poolingPeak<minIdle是因为里面可能有丢弃的连接,这样会导致poolingPeak不准确。

注意这里只是锁住了连接数量的更改,而没有去锁连接创建的代码,就是为了最大程度的进行并发。

createPhysicalConnection()创建物理连接时会初始化UsernamePasswordAutoCommitReadOnlyTransactionIsolation等属性,如果有设置就用你设置的,否则用默认的。

在这里插入图片描述

后续会执行connectionInitSqls ,这个是druid在连接初始化时会执行的sql,一般可以将一些需要提前初始化的sql放这里比如这种set names utf8mb4;

在这里插入图片描述

很奇怪的是专门用了variablesglobalVariables两个map将数据库里面的show variablesshow global variables对应参数装起来,不知道干嘛用的,但是PhysicalConnectionInfo这个类里面专门会存储,估计是一个比较重要的东西,后面看到再说。

将这些连接放到DruidConnectionHolder这个对象里面,构造函数如下:

在这里插入图片描述

对象里面有dataSourceconnect,刚才说的两个map,还有一个时间。将其整个放到DruidConnectionHolder[]数组这样一个连接池的底层实现里。

同步的实现就更粗暴简单了,直接循环创建连接,拿到真实物理连接之后封装进PhysicalConnectionInfo,在装进DruidConnectionHolder里,最后扔进DruidConnectionHolder[]线程池里。

思考和疑问

至此整个DruidDataSource类差不多理清楚了,但是还有很多细节没太想明白,比如:

  • createAndStartCreatorThread()createAndStartDestroyThread()这两个守护线程是干嘛的?为啥要设成守护线程而不是直接的线程?
  • DruidPooledConnection里面又有conn和holder,conn可以通过holder的getConnection()拿到,为啥要单独设置一个成员变量?意义何在?
  • Filter的作用和实现
  • Wrapper干嘛的(好像是JDBC基础知识?)
最后

后续按照上面问题的线一个个解决吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值