hikaripool信息_HikariPool源码(四)资源状态[通俗易懂]

hikaripool信息_HikariPool源码(四)资源状态[通俗易懂]Java极客|作者/铿然一叶这是Java极客的第55篇原创文章1.本章目的了解池资源的状态,以及状态如何变迁,用于池化资源设计参考。2.HikariPool资源核心类回顾HikariPool资源相关的类如下:类说明:类职责HikariPool资源池,客户端资源操作的入口。ConcurrentBag通用的并发包工具。CopyOnWriteArrayList一个列表,用于存储资源,…

大家好,又见面了,我是你们的朋友全栈君。

hikaripool信息_HikariPool源码(四)资源状态[通俗易懂]

Java极客  |  作者  /  铿然一叶

这是Java极客的第 55 篇原创文章

1.本章目的

了解池资源的状态,以及状态如何变迁,用于池化资源设计参考。

2.HikariPool资源核心类回顾

HikariPool资源相关的类如下:

hikaripool信息_HikariPool源码(四)资源状态[通俗易懂]

类说明:

职责

HikariPool

资源池,客户端资源操作的入口。

ConcurrentBag

通用的并发包工具。

CopyOnWriteArrayList

一个列表,用于存储资源,也就是PoolEntry。其特点是读不加锁,写操作加锁,提高并发性能。

PoolEntry

资源封装类,封装了Connection,资源的状态记录在这个类上。

Connection

真正要适用的资源,数据库连接。

3.资源状态

在PoolEntry上实际有两个状态或者说属性,分别是:

3.1 state

state用于声明资源是否可用,其状态变化如下:hikaripool信息_HikariPool源码(四)资源状态[通俗易懂]

状态

何时变化

Not In Use

1.连接池初始化时

2.释放资源回池时

3.出借资源,资源不够时

In Use

出借可用资源时。

Reserved

1.资源超过最大生命周期时

2.资源池shutdown时

3.Detect retrograde time时

4.调用者主动调用时。

Removed

1.连接池初始化,动态伸缩时(降时)

2.获取连接时

3.发生特定异常时。

3.1.1 Not In Use

这个状态说明资源没有被使用,等待分配,资源刚初始化好或者释放回资源池中的资源将变成这个状态。

1.连接池初始化时,连接池中的资源初始化并达到最小资源数,这些初始化的资源就是这个状态。

2.资源使用完释放会池中时,资源状态会从In Use变成Not In Use。

3.出借资源,资源不足时,此时如果池中的资源数没有达到最大资源数,则会创建新的资源,新资源状态也是这个状态。

3.1.2 In Use

唯一的场景就是出借资源后,资源从Not In Use变成In Use。

3.1.3 Reserved

1.资源超过最大生命周期时是指:每一个资源实例可以设置最大生命周期,如果超过最大生命周期还没有使用(Not In Use)则会调整为Reserved状态,这个状态下资源不能被使用。

2.资源池shoudown时也会先将资源的状态从Not In Use修改为Reserved状态,避免再被出借出去。

3.Detect retrograde time时,是一个很特殊的场景,这是检查时钟同步时是否回拨了,这个场景我们一般不会考虑到,参考代码如下:

//HouseKeeper.java

// Detect retrograde time, allowing +128ms as per NTP spec.

if (plusMillis(now, 128) < plusMillis(previous, housekeepingPeriodMs)) {

logger.warn(“{} – Retrograde clock change detected (housekeeper delta={}), soft-evicting connections from pool.”,

poolName, elapsedDisplayString(previous, now));

previous = now;

softEvictConnections();

return;

}

复制代码

资源什么时候超过最大生命周期,是通过一个延迟的线程任务来执行,如果线程执行了,资源还没有被使用,说明超过了最大生命周期。

4.允许调用者主动调用方法来设置这个状态,HikariPool中没有直接调用点。代码如下:

//HikariDataSource.java

/**

* Evict a connection from the pool. If the connection has already been closed (returned to the pool)

* this may result in a “soft” eviction; the connection will be evicted sometime in the future if it is

* currently in use. If the connection has not been closed, the eviction is immediate.

*

* @param connection the connection to evict from the pool

*/

public void evictConnection(Connection connection){

HikariPool p;

if (!isClosed() && (p = pool) != null && connection.getClass().getName().startsWith(“com.zaxxer.hikari”)) {

p.evictConnection(connection);

}

}

复制代码

3.1.4 Removed

这个状态意味着资源从连接池中清除,数据库连接被真正关闭,资源被释放。

1.连接池初始化,动态伸缩时(降时),这是指资源数量超过最小连接数,并且部分连接的闲置时间也已经超过允许的闲置时间,那么就会释放这些连接,使得池中的资源数量降到最小连接数。

2.获取连接时,通常我们不可能在此时去释放连接,这里是因为当连接池shutdown时,有的连接可能被设置为evicted,这样的连接是不可用的,对这样的连接要释放掉,导致这个场景发生的原因这两个动作没有加锁,而不加锁的目的是为了提升性能,毕竟这种场景并不多见,大多数时候不会出现,也就在大多数情况下提升了性能。

3.发生特定异常时,这类异常都是直接导致数据库连接不可用的异常,因此会将数据库连接释放掉。

3.2 evict

资源的另外一个状态或者属性是evict标志,如果标志为true,就意味着资源不可用。其状态变化比较简单,默认为false。

hikaripool信息_HikariPool源码(四)资源状态[通俗易懂]

这个标记最主要的作用是在获取资源时,如果资源的evict标志为true,则这个资源不可用,会接着获取下一个资源。

资源变为true的时机可参考state变为removed的时机,可以理解为就是资源不可用,将要清理并释放掉的时候。

从上面两个状态的变化来看,似乎用removed状态可以替代evict为true,但是在HikariPool中并没有这么做,一方面可能是因为从业务上讲两者的业务含义不同,另外一方面evict还用在异常处理中,对于异常的处理这里不再深入展开,有兴趣可以看下源码。

4. 总结

HikariPool使用了资源状态来控制资源是否可用,而不是通过一个可用资源池和一个已用资源池来控制资源可用,这么做的好处有:

控制粒度更小,更精确,不需要在池上加锁,只要在具体资源上加锁,符合并发编程优化的减小锁粒度原则

扩展更容易,如果通过不同的池来控制,那么增加新的状态,会导致要增加新的池来记录这些资源。

HikariPool使用了state和evict来控制资源的使用,实际设计时是否需要如此,要结合实际情况来看:

从解耦的角度看,如果业务上是两个业务语义,并且不同语义有不同用途,那么就分开。

如果实际业务只需要一个state就够了,就没有必要一开始就拆分为两个,可遵循适用原则,等有需要时再扩展。

end.

hikaripool信息_HikariPool源码(四)资源状态[通俗易懂]

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/152350.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 基本积分公式表_不定积分公式表大全

    基本积分公式表_不定积分公式表大全\(\large\intkdx=kx+C\)\(\large\intx^adx=\frac{x^{\alpha+1}}{\alpha+1}+C\)\(\large\int\frac{1

    2022年8月4日
    3
  • mysql 快速导入数据_MySQL导入数据

    mysql 快速导入数据_MySQL导入数据有时候需要批量插入一批数据到数据库,有很多种办法,这里我用到过三种办法:1、通过Excel直接生成insert语句=CONCATENATE(&amp;amp;quot;insertintoaisee_pingfen_fengcai(id,order_n,department,subject_n,teacher_name)values(‘&amp;amp;quot;,A1,&amp;amp;quot;’,’&amp;amp;quot;,B1,&amp;

    2022年9月21日
    0
  • datax(5):改造升级-自动识别py环境,执行datax任务

    datax(5):改造升级-自动识别py环境,执行datax任务1思考上篇文章已经研究过datax.py文件,产生2个问题:如果用户不是py2环境(datax默认要求环境)怎么处理;能不能有一个脚本自动识别用户的py环境,从而执行datax任务2效果在py2或py3下执行下面命令>pythondatax.py../job/job.json熟悉的配方,熟悉的味道。什么都没有变,但是背后却做了很多事情;3改造过程3.1编写py3的datax脚本共计3个文件===datax.py文件===#!/usr/bin/envpyt.

    2022年5月17日
    94
  • pycharm2022.01.13 激活码【2022.01最新】

    (pycharm2022.01.13 激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~2KLK…

    2022年4月1日
    65
  • 快速生成数据库ER图的方式[通俗易懂]

    快速生成数据库ER图的方式[通俗易懂]dbdiagram简述快速简单的数据库模型设计工具,可以帮助您使用其自己的特定于域的语言(DSL)来绘制数据库图。最主要的是免费。dbdiagram地址https://dbdiagram.io/dbdiagram效果Draw.io简介对于基于Web的使用免费,对于Atlassian(Confluence/JIRA)应用则需要付费。特点Draw.io是一个免费的在线图表软件,用于制作流程图,流程图等。允许使用不同类型的图表,例如流程图,组织结构图,UML,ER和网络图。允许

    2022年6月21日
    227
  • pycharm导入Python_python简单项目

    pycharm导入Python_python简单项目1安装Anaconda1、安装anocandahttps://www.jianshu.com/p/d3a5ec1d9a082、配置anocanda环境变量3、测试安装成功看到如下就安装成功了2python3.81、安装软件等待安装完成!2、添加python的环境变量3、测试成功3、pycharm导入python项目1、打开对应的项目2、将python3.8导入该项目中遇到如下问题:(如

    2022年8月28日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号