最近公司要求基于阿里的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. SharePoint客户端对象模型—任务日历生成

    1,憋了好几天在经理帮助下用Js根据任务列表,生成的个人任务日历. (1)需要用到的CSS样式 <style type="text/css"> th.ms-vh { c ...

  2. JOB SERVER 负载均衡

    JOB SERVER 负载均衡 一.体系结构 1.job server group job server group 是由一个或者多个job server 组成的,做为一个整体对外提供服务,在内部实现 ...

  3. Scala相关笔记

    一.Scala概述以及安装 1.   什么是Scala Scala 是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性.Scala 运行于 Java 平台(Java 虚拟机 ...

  4. Ubuntu18.04挂载exfat格式移动硬盘

    1.安装exfat-fuse 命令:sudo apt-get install exfat-fuse 2.重新插拔移动硬盘,即可识别 查看挂载命令:lsblk

  5. (二)ubuntu下安装Amd RX470驱动

    0X:ADM官方下载驱动 https://www.amd.com/en/support 查看本机驱动命令 lspci | grep -i vga 选择自己的驱动 下载对应的版本 现在最新的是:amdg ...

  6. redis学习笔记(三)

    Spring data redis: 要求: Redis 版本 > 2.6 与 Lettuce 或 Jedis 集成,两种java开源Redis库. Spring redis主要做的两件事: 连 ...

  7. [试玩] FMXLinux (Firemonkey for Linux) Linux 桌面开发(第三方插件)

    FMXLinux 是一个可以用来开发 Linux 桌面软件的第三方插件,它需要配合 Delphi 10.2 Toyko 官网:http://www.fmxlinux.com/ 使用方法:开启 FMX ...

  8. (数据科学学习手札52)pandas中的ExcelWriter和ExcelFile

    一.简介 pandas中的ExcelFile()和ExcelWriter(),是pandas中对excel表格文件进行读写相关操作非常方便快捷的类,尤其是在对含有多个sheet的excel文件进行操控 ...

  9. SSM-CRUD入门项目——查询

    查询 1.基础查询 分析:访问项目主页 index.jsp 时应该跳转到列表页 我们可以在index.jsp发出查询员工列表请求,来到 list.jsp 使用插件 pageHelper 完成分页功能— ...

  10. 2017-2018-1 《信息安全技术》实验二——Windows口令破解

    2017-2018-1 <信息安全技术>实验二--Windows口令破解 所用工具 系统:能勾起我回忆的Windows 2003 工具:LC5.SuperDic Windows口令破解 口 ...