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)
blank

相关推荐

  • @Validated注解使用

    @Validated注解使用@ValidatedpublicStringsyncTable(@ValidatedSyncByTableRequestrequest){logger.debug(&amp;quot;request_info:&amp;quot;+JsonUtil.toJson(request));Stringresponse=Response.success(syncService….

    2022年10月27日
  • GPU利用率低的解决办法

    GPU利用率低的解决办法watch-n0.1-dnvidia-smi#检查GPU利用率参数解决办法:1.dataloader设置参数2.增大batchsize3.减少IO操作,比如tensorboard的写入和打印。4.换显卡

  • 解决SVN安装语言包后无法选择中文的问题(亲测可行)

    解决SVN安装语言包后无法选择中文的问题(亲测可行)

  • java jce_了解Java JCE的加密

    java jce_了解Java JCE的加密阅读提示:Java密码扩展(TheJavaCryptographyExtension),是JDK1.4的一个重要部分,本文介绍JCE的安装和使用。首先演示如果安装配置JCE(静态安装),然后是如何在不安装的情况下使用JCE(动态安装)。最后,将演示怎么生成密钥和密码,及如果进行基本的加密、解密。Java密码扩展(TheJavaCryptographyExtension),是JDK1.4…

  • CUDA编程注意(CUDA编程)

    CUDA编程注意传给CUDA编译器编译的文件里不能包含boost的头文件,会报错。例如xxCUDA.cuh中最好不要包含boost的头文件。CUDA编程中核函数一般写在.cu文件中,也可以使用.cu生成的ptx文件(起到了类似OpenGL中的着色器的作用)添加到C++的程序中,cuda给了一套使用ptx编程的接口,这使得CUDA程序不需要.cu文件。详情见https://www.cnblogs…

  • matlab中importdata无法打开文件_importdata无法打开文件

    matlab中importdata无法打开文件_importdata无法打开文件最近使用importdata函数不能读取全部数据,数据集315行,但是读取了197行,那就是197-198之间有问题,百度之后有了思路。由于没有找到具体的证据,所以这里说一下解决思路。import可以导入很多文件类型,.dat文件应该默认的是ASCII码,在编码处看到(我用的notepad++)使用的UTF-8编码,修改为使用ANSI编码,看一下结果UTF-8编码ANSI编码果然有问题,删除就可以了。这个数据是直接从网页端复制的,所以应该是哪里出了问题。…

发表回复

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

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