最近公司要求基于阿里的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源码分析的更多相关文章

  1. druid 源码分析与学习(含详细监控设计思路的彩蛋)(转)

    原文路径:http://herman-liu76.iteye.com/blog/2308563  Druid是阿里巴巴公司的数据库连接池工具,昨天突然想学习一下阿里的druid源码,于是下载下来分析了 ...

  2. 精尽MyBatis源码分析 - MyBatis-Spring 源码分析

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  3. Spring系列28:@Transactional事务源码分析

    本文内容 @Transactional事务使用 @EnableTransactionManagement 详解 @Transactional事务属性的解析 TransactionInterceptor ...

  4. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  5. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  6. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  7. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  8. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  9. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

随机推荐

  1. 用JavaScript编写简单斗地主效果Es6

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. js怎样得出数组中某个数据最大连续出现的次数

     1:js怎样得出数组中某个数据最大连续出现的次数 var test=[1,2,3,3,2,2,2,3,3,3,3,5,3,3,3,3,3] ;    var j  = 0 ;    var max  ...

  3. 浅谈OSI七层网络模型和TCP/IP四层模型

    OSI七层网络模型 OSI(Open System Interconnection)开放系统互连参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系. OSI七层模型 功能 ...

  4. 在javascript中什么是伪数组,如何将伪数组转化为标准数组?

    这里把符合以下条件的对象称为伪数组: 1.具有length属性 2.按索引方式存储数据 3.不具有数组的push.pop等方法 伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的 ...

  5. 微信下载app需要点击右上角在浏览器中打开下载的问题

    很多朋友是不是遇到过这样的问题,自家的app通过微信推广没办法直接下载,而是需要通过一个遮罩层来提示用户下载. 点击下载按钮提示点击右上角在浏览器中打开 这样的方式下载一个app是不是需要点击下载按钮 ...

  6. 帝国CMS给会员注册加入问答验证

    修改文件有e/enews/index.php //注册 elseif($enews=="register") { if($_POST['ask']=='帝国软件') { $user ...

  7. (数据科学学习手札49)Scala中的模式匹配

    一.简介 Scala中的模式匹配类似Java中的switch语句,且更加稳健,本文就将针对Scala中模式匹配的一些基本实例进行介绍: 二.Scala中的模式匹配 2.1 基本格式 Scala中模式匹 ...

  8. vue搭建项目

    vue-cli 作用:快速搭建项目脚手架 安装3.0:npm i -g @vue/cli 安装桥接工具:npm i -g @vue/cli-init (vue-cli 3和旧版使用相同的命令,所以2被 ...

  9. MySQL - CentOS 下 MySQL 5.6 安装

    1. 概述 最近没啥东西可写, 随便写点 mysql 5.6 的安装 去年写的 装上去过 三次以上 2. 准备 系统 CentOS 7.4 3. 安装 1. 直接安装 # mysql服务端: mysq ...

  10. 20155207王雪纯 2006-2007-2 《Java程序设计》第二周学习总结

    20155207王雪纯 2006-2007-2 <Java程序设计>第二周学习总结 教材学习内容总结 整数类型:short(占2字节).int()占4字节.long(占8字节) " ...