DruidDataSource源码分析
最近公司要求基于阿里的DruidDataSource来做一个连接池监控 , 正好之前没有看过DruidDataSource的源码 , 便自己看了四个多小时写了一些自己的理解 , 给大家分享一下 , 如果有什么错误 , 欢迎指出!!!
DruidDataSource主要用到的是ReentrantLock锁,还有 notEmpty empty两个条件,生产连接与消费连接的线程在两个条件上等待与唤醒。
1创建连接
连接太多了的时候,在empty条件上等待,就是等空了再运行
// 防止创建超过maxActive数量的连接
if (activeCount + poolingCount >= maxActive) {
empty.await();
continue;
} connection = createPhysicalConnection();
setFailContinuous(false); boolean result = put(connection);
后面是创建一个物理连接,然后put一下,这个put是放池子中,主要下面几句:
holder = new DruidConnectionHolder(DruidDataSource.this, physicalConnectionInfo);
connections[poolingCount] = holder;
incrementPoolingCount();
notEmpty.signal();
notEmptySignalCount++;
2使用连接
DruidConnectionHolder takeLast()之中,当poolingCount中数量为0时等待。
正好说明使用连接的线程,当连接没有时,就等待。如果池中有连接就执行下面的语句:
decrementPoolingCount();
DruidConnectionHolder last = connections[poolingCount];//拿走池中最后一个
connections[poolingCount] = null;//最后一个赋值成null
获取链接的主要方法getPooledConnection()中调用takeLast(),又调用getConnection(),
这里面又是插入了过滤链来统计。filterChain.dataSource_connect()参数中有this,说明它把自己传进去了,
说明这个filterChain并不从属于任何datasource,可以是这个数据源,也可以是那个数据源。具体过滤哪个,临时传入。
3减少连接
在创建连接线程附近还有一个DestroyConnectionThread()
跟踪里面,有destroyTask.run();----->shrink(true);连接空闲的太多了就缩小。
在shrink()方法中,重点有下面的语句:
final int checkCount = poolingCount - minIdle;//池中的数量-最小空闲数量
for (DruidConnectionHolder item : evictList) {//可回收的DruidConnectionHolder
Connection connection = item.getConnection();
JdbcUtils.close(connection);
destroyCount.incrementAndGet();
}
4init()
创建线程与收缩线程都是由void init()来调用的,主要代码如下。
connections = new DruidConnectionHolder[maxActive];//新建连接池,个数是最大活动连接数maxActive。
for (int i = 0, size = getInitialSize(); i < size; ++i) {//放入连接池中连接
PhysicalConnectionInfo pyConnectInfo = createPhysicalConnection();
DruidConnectionHolder holder = new DruidConnectionHolder(this, pyConnectInfo);
connections[poolingCount] = holder;
incrementPoolingCount();
}
createAndLogThread();
createAndStartCreatorThread();//创建连接的线程,一直在工作,池子满了就是等待状态。
createAndStartDestroyThread();//收缩池子的线程,一直在工作。
initedLatch.await();//主线程在计数器为0前一直等待。
init = true;
这里有一个知识点。
CountDownLatch initedLatch = new CountDownLatch(2);
就叫倒计时同步器。当前同步数为2,在变成0后,主线程才能运行,否则一直等待中。
在创建连接与收缩池子的线程中都有initedLatch.countDown();,
一共正好两个,主线程就是等待上面两个线程都运行了才运行,才置init状态标识为true。
DruidDataSource源码分析的更多相关文章
- druid 源码分析与学习(含详细监控设计思路的彩蛋)(转)
原文路径:http://herman-liu76.iteye.com/blog/2308563 Druid是阿里巴巴公司的数据库连接池工具,昨天突然想学习一下阿里的druid源码,于是下载下来分析了 ...
- 精尽MyBatis源码分析 - MyBatis-Spring 源码分析
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- Spring系列28:@Transactional事务源码分析
本文内容 @Transactional事务使用 @EnableTransactionManagement 详解 @Transactional事务属性的解析 TransactionInterceptor ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
随机推荐
- TCL-事务
一.含义事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行二.特点(ACID)A 原子性:一个事务是不可再分割的整体,要么都执行要么都不执行C 一致性:一个事务可以使数据 ...
- 手机版的百度map封装,使用gps定位
代码如下,包自己引 包参考 一个百度MAP导航的基础封装 使用的是浏览器调用gps定位 修改了标注的大小 效果如图: 代码...... <!DOCTYPE html> <html&g ...
- ES6学习之-let 和const命令
let 和const命令 let命令 用来声明变量,类似于var .let声明的变量 只在let命令所在的代码块内有效. 在for循环里也是如此 每次循环其实都是一个代码块 function fn() ...
- spark or sparkstreaming的内存泄露问题?
关于sparkstreaming的无法正常产生数据---->到崩溃---->到数据读写极为缓慢(或块丢失?)问题 前两阶段请看我的博客:https://www.cnblogs.com/wa ...
- 大数据IDEA调试flink程序
Flink在IDEA中开发是一件比较困难的事情,网上没有参考资料,就算就业说的太过笼统,不知道是会了不说还是不会瞎说,为了解决flink这个问题,本人特别做了一遍开发的简单说明.主要考虑两个问题,1. ...
- python教程(六)·字符串
我们已经学习了字符串的使用方法,我们还学习了使用索引和分片操作字符串,经历了这么长的时间,相信大家也有所掌握:本节将讨论并学习字符串的格式化与字符串的常用方法 字符串格式化 字符串是序列的一种,所以所 ...
- express函数参数之next
关于next主要从三点来进行说明: next的作用是什么? 我们应该在何时使用next? next的内部实现机制是什么? 1.Next的作用 我们在定义express中间件函数的时候都 ...
- css position:absolute align center bottom
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Java程序设计 第16周 课堂实践 —— 数据库4
Java程序设计 第16周 课堂实践 -- 数据库4 课堂实践任务4 查询world数据库,查询哪个国家的平均寿命最长. 代码分析 实现查询数据库需要我们修改Message.java,MessageD ...
- 20155216 2016-2017-2 《Java程序设计》第二周学习总结
教材学习内容总结 类型 short占2字节 int占4字节 long占8字节 byte占1字节,可表示-128~127的整数 char占2字节 boolean不考虑占字节 float占4字节 doub ...