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对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
随机推荐
- 【Dubbo源码阅读系列】服务暴露之远程暴露
引言 什么叫 远程暴露 ?试着想象着这么一种场景:假设我们新增了一台服务器 A,专门用于发送短信提示给指定用户.那么问题来了,我们的 Message 服务上线之后,应该如何告知调用方服务器,服务器 A ...
- Oracle startup的四个阶段
shutdown->nomount->mount->open: 1.shutdown:数据库关闭 2.nomount: 1)$ORACLE_HOME/dbs下找初始化参数文件 a.s ...
- Linux 不杀进程的情况下,如何释放磁盘资源
最近项目组人员反馈一个问题:即磁盘空间满了,但是并没看到有什么文件占用空间: [root@xxxx home]# df -h Filesystem Size Used Avail Use% Mount ...
- ios 开发UI篇— UIToolbar
前言 NS_CLASS_AVAILABLE_IOS(2_0) __TVOS_PROHIBITED @interface UIToolbar : UIView <UIBarPositioning& ...
- css 中的 initial inherit unset 意思
写css时,在对属性进行选值,经常遇到unset , initial,inherit三个值.这几个值的含义. 1.inherit 可继承性 继承的意思. 每一个 CSS 属性都有一个特性就是,这个属性 ...
- python 判断是否是润年及函数封装
方法一, 从终端输入一个表示年份的整数,判断是否是闰年,是就打印xxx年是闰年,不是打印xxx年不是闰年 y = int(input('请输入一个年份:')) if (y % 4 == 0 and y ...
- 不可变字符串String与可变字符串StringBuilder、StringBuffer使用详解
String字符串 char类型只能表示一个字符,而String可以表示字符串,也就是一个字符序列.但String不是基本类型,而是一个定义好的类,是一个引用类型.在Java中,可以将字符串直接量赋给 ...
- vue中使用swiper并自定义分页器样式
一,安装swiper 执行命令 npm install vue-awesome-swiper --save 二,引入swiper import {Swiper} from "vue-awes ...
- thinkphp3.2 上传图片兼容小程序
第一步在配置文件中设置图片的大小和路径 return array( //'配置项'=>'配置值' 'img_save'=>[ 'size' =>[ 'app_gszc_Card'=& ...
- 在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all
在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all 前天来了个新需求, 有一个授权书的文件要点击下载, 需要在前端生成, ...