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源码(四)资源状态[通俗易懂]

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Django(39)使用redis配置缓存[通俗易懂]

    Django(39)使用redis配置缓存[通俗易懂]前言动态网站的基本权衡是,它们是动态的。每次用户请求页面时,Web服务器都会进行各种计算-从数据库查询到模板呈现再到业务逻辑-以创建站点访问者看到的页面。从处理开销的角度来看,这比标准的文件

  • Java面试个人简历

    Java面试个人简历姓名:郑清求职意向:Java开发工程师专业技能:熟练使用Java面向对象编程,具有良好的编程习惯以及CSDN技术文档编写习惯;熟练使用Eclipse/IDEA等开发工具;熟练SVN,Maven,Git等项目管理工具;熟练Spring,SpringMVC,Hibernate,MyBatis等开源框架技术;掌握SpringBoot+SpringCloud微服务架构;掌握My…

  • HTC M7日文版HTL22刷机包 毒蛇2.5.0 ART NFC Sense6.0

    HTC M7日文版HTL22刷机包 毒蛇2.5.0 ART NFC Sense6.0

  • 2022年 – 2023年 最新计算机毕业设计 本科 选题大全 汇总

    2022年 – 2023年 最新计算机毕业设计 本科 选题大全 汇总文章目录0前言1javaweb管理系统毕设选题2javaweb平台/业务系统毕设选题3游戏设计、动画设计类毕设选题(适合数媒的同学)4算法开发5数据挖掘毕设选题6大数据处理、云计算、区块链毕设选题7网络安全毕设选题8通信类/网络工程毕设选题9嵌入式毕设选题10开题指导0前言Hi,大家好,这里是丹成学长,大四的同学马上要开始毕业设计啦,大家做好准备了没!学长给大家详细整理了计算机毕设最新选题,对选题有任何疑问,都可以问学长哦~1javaweb

  • javascript 数组复制「建议收藏」

    javascript 数组复制「建议收藏」javascript数组复制数组不能直接等于一个数组例如vararr=arr1数组是内置对象,存储的是数组的地址,这样复制就等于复制了地址,更改一个数组的值,另一个也会更改复制方法slice()数组截取vararr=[1,2,3]vararr2=arr.splice();…

  • OpenSSL、OpenSSL-FIPS、OpenSSL-FIPS-ECP的区别

    OpenSSL、OpenSSL-FIPS、OpenSSL-FIPS-ECP的区别在OpenSSL的官网上可以看到三个分支,分别是openssl-、openssl-fips-、openssl-fips-ecp-。这三者的区别如下。 分支 内容差异 openssl- 完整版的OpenSSL openssl-fips- 把密码函数库单独抽出来,做成一个满足FIPS1…

发表回复

您的电子邮箱地址不会被公开。

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