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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm2021 激活码破解方法

    pycharm2021 激活码破解方法,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月14日
    68
  • 2021vue经典面试题_vue面试题大全

    2021vue经典面试题_vue面试题大全面试题(2020)Vue面试题汇总博客说明文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!1、对于MVVM的理解MVVM是Model-View-ViewModel的缩写。Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。View代表UI组件,它负责将数据模型转化成UI展现出来。ViewModel监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View和Model的对

    2022年10月9日
    5
  • 讲解最到位的粒子群算法,附matlab代码求解函数最优值

    讲解最到位的粒子群算法,附matlab代码求解函数最优值从鸟群觅食行为到粒子群算法粒子群算法的核心例:求解函数最小值粒子群算法的驱动因素从鸟群觅食行为到粒子群算法鸟群寻找食物的过程中,鸟与鸟之间存在着信息的交换,每只鸟搜索目前离食物最近的鸟的周围区域是找到食物的最简单有效的办法。粒子群算法(以下简称PSO)就是模拟鸟群觅食行为的一种彷生算法。解=粒子=鸟(鸟的位置象征着离食物的距离,粒子的位置也象征着…

    2022年5月31日
    68
  • 永磁直流无刷电机驱动器_永磁直流无刷电机的优缺点

    永磁直流无刷电机驱动器_永磁直流无刷电机的优缺点现实生活中我们接触的电机包括很多种类,除部分特殊种类外,永磁电机均是利用定子与转子磁场相互作用的原理制成。其中,使用直流电源驱动的电机称为直流电机,直流电机又可细分为直流有刷电机和直流无刷电机(BLDC)。电刷,是区分“有刷”与“无刷”电机的关键,它是与换向器组合使用的电机组件,常见材质为金属和碳。带有换向器和电刷的电机称为有刷电机,使用电子电路实现换向功能的电机称为无刷电机。直流有刷电…

    2022年10月21日
    1
  • linux(6)查看进程ps命令[通俗易懂]

    linux(6)查看进程ps命令[通俗易懂]ps命令Linuxps(英文全拼:processstatus)命令用于显示当前进程的状态,类似于windows的任务管理器查看所有进程ps-A显示所有进程信息,连同命令行ps-

    2022年7月29日
    10
  • TCL语法_日语语法整理手写笔记

    TCL语法_日语语法整理手写笔记一、什么是TCLTcl全称是ToolcommandLanguage。它是一个基于字符串的命令语言,基础结构和语法非常简单,易于学习和掌握。Tcl语言是一个解释性语言,所谓解释性是指不象其

    2022年8月5日
    4

发表回复

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

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