commons-pool2源码走读(四) 对象池实现GenericObjectPool

2023-10-30

commons-pool2源码走读(四) 对象池实现GenericObjectPool<T>

GenericObjectPool <T> 是一个可配置的ObjectPool实现。
当与适当的PooledObjectFactory组合使用时,GenericObjectPool为任意对象提供健壮的池功能。

您可以选择性的配置池来检查和可能回收池中的空闲对象,并确保有最少数量的空闲对象可用。这是由一个“空闲对象回收”线程(即BaseGenericObjectPool <T> 的Evictor)执行的,线程是异步运行的。在配置这个可选特性时,应该谨慎使用。驱逐运行与客户端线程争用池中的对象,因此如果它们运行得太频繁,可能会导致性能问题。

还可以配置池来检测和删除被泄漏的对象,比如一个从池中借出的对象,在超过removeAbandonedTimeout超时之前既不使用也不返回。移除泄漏的连接,可能发生在对象被借用时对象池已接近饱和,也可能是被回收线程检查出,或者两者都执行时。如果池对象实现了TrackedUse接口,那么其最后一次使用时间使取决于getLastUsed方法;否则,是由对象从池中借出的时间决定。

实现注意:为了防止可能的死锁,已经采取了谨慎措施,以确保在同步块中不会发生对工厂方法的调用。这个类线程安全。

1、接口继承、实现关系

GenericObjectPool <T> 实现了ObjectPool<T> 具备对象池的功能,同时 继承了BaseGenericObjectPool<T> 的对于对象状态管理和回收等功能。
这里写图片描述

2、构造函数

构造函数通过GenericObjectPoolConfig 和PooledObjectFactory来进行参数的初始化和对象工厂类的引入。

    public GenericObjectPool(final PooledObjectFactory<T> factory,
            final GenericObjectPoolConfig config) {
        //父类BaseGenericObjectPool构造方法
        super(config, ONAME_BASE, config.getJmxNamePrefix());

        if (factory == null) {
            jmxUnregister(); // tidy up
            throw new IllegalArgumentException("factory may not be null");
        }
        this.factory = factory;
        //空闲对象队列,此队列非JDK而是自行实现的一个队列
        idleObjects = new LinkedBlockingDeque<>(config.getFairness());
        //覆盖BaseGenericObjectPool里面的配置参数
        setConfig(config);
        //初始化回收线程
        startEvictor(getTimeBetweenEvictionRunsMillis());
    }

3、相关属性

    // --- 可配置的属性 -------------------------------------------------
    //最大空闲数量
    private volatile int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
    //最小空闲数量
    private volatile int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;
    //对象工厂
    private final PooledObjectFactory<T> factory;

    // --- 内部属性 -------------------------------------------------

    //池中所有的对象,只能是<=maxActive
    private final Map<IdentityWrapper<T>, PooledObject<T>> allObjects =
        new ConcurrentHashMap<>();
    //已创建对象总数(不包含已销毁的)
    private final AtomicLong createCount = new AtomicLong(0);
    //调用创建方法总线程数
    private long makeObjectCount = 0;
    //makeObjectCount 增长时并发锁
    private final Object makeObjectCountLock = new Object();
    //空闲对象队列
    private final LinkedBlockingDeque<PooledObject<T>> idleObjects;

    // JMX specific attributes
    private static final String ONAME_BASE =
        "org.apache.commons.pool2:type=GenericObjectPool,name=";

    //泄漏对象回收配置参数
    private volatile AbandonedConfig abandonedConfig = null;

4、 对象池方法实现

  • 借用对象
    整个流程为,检查池是否关闭 –> 是否回收泄漏对象 –> 是否阻塞创建对象 –> 创建对象 –> 分配对象 –> 激活对象 –> 校验对象 –> 更改借用信息 –> 返回对象
   public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
        //判断对象池是否关闭:BaseGenericObjectPool.closed==true
        assertOpen();
        //如果回收泄漏的参数配置不为空,并且removeAbandonedOnBorrow参数配置为true
        //并且Idle数量<2,Active数量>总数Total-3
        //在借用时进行回收泄漏连接(会影响性能)
        final AbandonedConfig ac = this.abandonedConfig;
        if (ac != null && ac.getRemoveAbandonedOnBorrow() &&
                (getNumIdle() < 2) &&
                (getNumActive() > getMaxTotal() - 3) ) {
            //回收泄漏对象
            removeAbandoned(ac);
        }

        PooledObject<T> p = null;

        //copy blockWhenExhausted 防止其它线程更改getBlockWhenExhausted值造成并发问题
        //借用对象时如果没有是否阻塞直到有对象产生
        final boolean blockWhenExhausted = getBlockWhenExhausted();
        //创建成功标识
        boolean create;
        //记录当前时间,用作记录借用操作总共花费的时间
        final long waitTime = System.currentTimeMillis();
        //当对象为空时一直获取
        while (p == null) {
            create = false;
            //从双端队列弹出第一个队首对象,为空返回null
            p = idleObjects.pollFirst();
            //如果为空则重新创建一个对象
            if (p == null) {
                //创建对象
                p = create();
                //p==null可能对象池达到上限不能继续创建!
                if (p != null) {
                    create = true;
                }
            }
            //如果对象p还是为空则阻塞等待
            if (blockWhenExhausted) {
                
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

commons-pool2源码走读(四) 对象池实现GenericObjectPool 的相关文章

  • 从txt文件中读取数据而不下载它?

    我想从提供的文本文件中解析信息 有没有一种方法可以在应用程序中执行此操作 而无需先下载文件 以某种方式传输文本内容 打开到 URL 的 Http 连接 使用内置 HttpURLConnection 或使用 commons httpclien
  • IBM Websphere MQ - 用于 Tomcat 部署的 EJB 和 MDB 迁移

    我已经为此苦苦挣扎了很长一段时间 我有一个 IBM Websphere MQ 它使用 EJB 和 MDB 以下是配置ejb mdb的地方
  • 在java代码中创建postgresql表

    我有一个与 postgreSQL 数据库连接的 java 代码 现在 我希望当它连接到数据库时 我还将创建数据库表 但我的问题是 它不会创建数据库 我不知道问题是什么 这是我的代码 Statement st null ResultSet r
  • Android Studio 与 Google Play 服务的编译问题

    我正在运行 Android Studio 0 8 4 并在 Android Studio 0 8 2 上尝试过此操作 我正在运行 Java JDK 1 8 0 11 并尝试使用 JDK 1 8 0 05 每当我尝试构建我的 android
  • Spring Data Jpa OneToMany 同时保存子实体和父实体?

    这是我的父实体 注意 为了简洁起见 删除了 getter setter lombok 注释 Entity public class Board Id GeneratedValue strategy GenerationType IDENTI
  • 如何杀死 Java Future?

    我正在开发的服务使用 Future 来并行运行多个任务 每个任务最多可能需要一分钟才能完成 然而 外部库似乎有问题 因为在某些情况下 2 的时间 它不会返回 在这些情况下 我想给出 2 分钟的等待时间 如果还没有返回 我想杀死 future
  • Java:一种将 Mime(内容)类型与 CommonsMultipartFile 中的文件扩展名相匹配的方法

    在我的公司 出于额外原因 我需要将 mime 类型与文件扩展名进行比较 我有一个CommonsMultipartFile 我正在尝试找出进行这种比较的最佳方法 我见过一个MimetypesFileTypeMap 但不确定这是否适用于此 我试
  • 当前平台不支持桌面 API

    我遇到过这个错误 java lang UnsupportedOperationException 当前平台不支持桌面 API 我将从我的 java 应用程序中打开一个文件 我用这个方法 Desktop getDesktop open new
  • 使用 https 的 Web 服务身份验证给出错误

    我编写了一个简单的 Web 服务 并使用摘要和 HTTPS 身份验证来保护它 我已经使用 Java 中的 keytool 生成了我的证书 当我通过创建 war 文件在 Tomcat 中部署 Web 服务时 axis 的欢迎页面正确显示 但是
  • 使用正则表达式验证电子邮件的最大长度

    我找到了用于电子邮件验证的正则表达式 a z0 9 a z0 9 a z0 9 a z0 9 a z 2 4 我希望电子邮件的最大长度为 20 个字符 因此我将其更改为 a z0 9 a z0 9 a z0 9 a z0 9 a z 2 4
  • JFrame 在连续运行代码时冻结

    我在使用时遇到问题JFrame 它会冻结 连续运行代码 下面是我的代码 点击时btnRun 我调用了该函数MainLoop ActionListener btnRun Click new ActionListener Override pu
  • java绕中心旋转矩形

    我想围绕其中心点旋转一个矩形 它应该保留在应该绘制的位置并在该空间中旋转 这是我的代码 AffineTransform transform new AffineTransform transform rotate Math toRadian
  • 如何获取 JDBC 中 UPDATE 查询影响的所有行?

    我有一项任务需要使用更新记录PreparedStatement 一旦记录被更新 我们知道更新查询返回计数 即受影响的行数 但是 我想要的不是计数 而是受更新查询影响的行作为响应 或者至少是受影响的行的 id 值列表 这是我的更新查询 UPD
  • 在约束验证器中使用 Guice 进行依赖注入

    我有一个在 ConstraintValidator 的实现中注入类的用例 我正在使用 Google guice 进行依赖项注入 目前无法在验证器内注入 我的场景的简化形式 内部模块 Provides Singleton public Ser
  • javadoc 子集/java 库组织

    我自己从来没有运行过javadoc 无论是在命令行还是ant 的 javadoc 任务 http ant apache org manual Tasks javadoc html 我将使用 ant 我需要为我编写的库生成 javadoc 问
  • Spring Security 角色层次结构不适用于 Thymeleaf sec:authorize

    我正在使用 Spring Security 3 2 5 RELEASE 和 ThymeLeaf 2 1 4 RELEASE 我已经在安全上下文中定义了角色层次结构 在我的视图层中我正在使用sec authorize属性来定义菜单项 我希望看
  • 添加 char 和 int

    据我了解 字符是一个字符 即一个字母 一个digit 标点符号 制表符 空格或类似的东西 因此 当我这样做时 char c 1 System out println c 输出 1 正是我所期望的 那么为什么当我这样做时 int a 1 ch
  • 如何更改 JAX-WS Web 服务的地址位置

    我们目前已经公开了具有以下 URL 的 JAX RPC Web 服务 http xx xx xx xx myservice MYGatewaySoapHttpPort wsdl http xx xx xx xx myservice MYGa
  • Spring 如何在运行时获取有关“强类型集合”的泛型类型信息?

    我在 Spring 3 0 文档中阅读了以下内容 强类型集合 仅限 Java 5 在 Java 5 及更高版本中 您可以使用强类型集合 使用泛型类型 也就是说 可以声明一个 Collection 类型 使其只能包含 String 元素 例如
  • FragmentMap + ActionBar 选项卡

    我一直在尝试插入一个MapView进入一个ActionBar Tab 但我什至无法解决问题 即使谷歌搜索 这是主要活动 Override public void onCreate Bundle savedInstanceState supe

随机推荐

  • vue中视频插件vue-video-player使用

    视频插件 vue video player github地址 https github com surmon china vue video player 安装 npm install vue video player save 引入 全局
  • Application进行详解(unity)

    Application进行详解 unity中的 介绍 在Unity引擎中 Application类是一个非常重要的类 它可以提供一些有用的方法 用于管理Unity应用程序的运行时行为 通过使用Application类 您可以获取有关Unit
  • 剑指offer62. 圆圈中最后剩下的数字(Josephuse约瑟夫环问题) P300

    剑指offer62 圆圈中最后剩下的数字 Josephuse约瑟夫环问题 P300 题目 0 1 n 1这n个数字排成一个圆圈 从数字0开始每次从这个圆圈里删除第m个数字 求出这个圆圈里剩下的最后一个数字 方法1 循环链表 C 官网说lis
  • TextMeshProUGUI的基本使用方法(资源创建、材质、表情等)

    TextMeshPro 以下均简称为TMP 是使用在Unity中的一种强大的文本插件 恩 感觉跟PS差不多了 在unity5 6时代好像就说要用这个插件来代替unity中自带的Text和TextMesh组件 但现在都unity2017 3了
  • 【Kubernetes部署篇】Kubeadm方式搭建K8s集群 1.26.0版本

    文章目录 一 集群规划及架构 二 系统初始化准备 所有节点同步操作 三 安装并配置Containerd容器运行时 四 安装kubeadm 所有节点同步操作 五 初始化集群 六 Node节点添加到集群 七 安装网络组件Calico 八 测试C
  • 13. PyQt5实现多页面切换之QTabWidget

    PyQt5实现多页面切换之QTabWidget PyQt5实现多页面切换之QTabWidget 一 QTabWidget 类简介 二 QTabWidget 类的使用步骤 三 QTabWidget 类中的属性 四 QTabWidget 类中的
  • 抖音广告落地页怎么制作?四个原则为您详细介绍

    抖音广告落地页怎么制作 抖音作为著名的短视频社交平台 活跃用户数据庞大 消费市场广阔 已经成为了品牌商重要的产品网络推广平台 抖音信息流广告亦是成为各大品牌商的热门选择 那么一个引人入胜的抖音广告落地页该如何制作呢 1 辨识原则 利用品牌方
  • STM32H7实现8通道ADC采集(软件触发+DMA传输)

    使用CubeMX工具 对DMA进行配置 CubeMX工程下载 dma相关的配置比较简单 主要是adc配置相关的修改 数据要设置成DMA循环模式ADC CONVERSIONDATA DMA CIRCULAR 溢出操作要设置为覆盖ADC OVR
  • auto-1 - 自动化之windows powershell与python

    在powershell中实现功能 mkvenv指令在该目录下创建并进入虚拟环境 如果目录中有requirements txt自动安装 venv进入该目录下的虚拟环境 默认虚拟环境文件夹名称是venv pi
  • 解决:ModuleNotFoundError: No module named ‘gym‘

    从没安装过gym 出现 ModuleNotFoundError No module named gym 这种错误 可以使用命令如下进行安装 pip install i https pypi tuna tsinghua edu cn simp
  • 学习笔记(28):R语言入门基础-矩阵的编辑——合并矩阵

    立即学习 https edu csdn net course play 24913 285695 utm source blogtoedu 矩阵的合并 按行合并 rbind 按列合并 cbind
  • 旅游管理系统-JAVA【数据库设计、源码、开题报告】

    摘 要 21世纪是一个知识大爆炸的时代 互联网拉近了人们的距离 信息化革命席卷了各个行业 物质生活水平的提高使得人们的消费观念悄然发生改变 人们对户外旅行的要求越来越高 这对于传统旅游行业来说既是机遇也是挑战 提高旅游行业管理水平 推进旅游
  • 转载:开源mes系统_基于SpringBoot 开源框架,设计MES系统源码分享(代码标准规范)

    Hutool 是一个小而全的Java工具类库 通过静态方法封装 降低相关API的学习成本 提高工作效率 使Java拥有函数式语言般的优雅 让Java语言也可以 甜甜的 请求参数每张表的分页查询参数 严格按照一张表对应一个请求参数对象进行开发
  • NTSC、PAL、SECAM彩色电视制式

    NTSC PAL和SECAM是世界上最主要的三大电视制式 并且这三种制式间不能兼容 例如PAL的视频不能在NTSC制式的电视上播放 下图是三种制式在世界上的使用分布图 NTSC制式 NTSC制式 简称N制 是1952年12月由美国国家电视标
  • 老公老婆

    1 老公 你要努力挣钱 钱这个东西 不能少得来让我们整日为生计发愁 最好也不能多得来需要别的女人帮着花 2 请给我关爱 信任 尊重和自由 3 你要加强锻炼 强健身体 好在我们共同返家的夜晚 一口气抱我上到五楼的家门 我渴望每天都能做你的新娘
  • 21天Python进阶学习挑战赛

    21天Python进阶学习挑战赛活动详情 1 活动介绍 2 作者介绍 3 专栏介绍 4 学习计划 1 活动介绍 CSDN与每一位学习者同行 平台优质专栏作者带队精准学习 精选高质量专栏学习资料活动期内限时免费学习 此刻开启学习打卡之路 收获
  • LETTERS

    http poj org problem id 1154 Description A single player game is played on a rectangular board divided in R rows and C c
  • 大数据从0到1的完美落地之sqoop命令执行

    Sqoop命令执行 常见命令执行参数 通过Sqoop加不同参数可以执行导入导出 通过sqoop help 可以查看常见的命令行 常见Sqoop参数 root qianfeng01 sqoop 1 4 7 sqoop help codegen
  • 前端面试 - 项目流程

    目录 1 项目流程 2 项目角色 3 完整项目流程 4 项目沟通 5 PM想在开发过程中增加需求 该怎么办 6 项目即将延期了 该怎么办 7 你将如何保证项目质量 1 项目流程 1 项目分多人 多角色参与 2 项目分多阶段 3 项目需要计划
  • commons-pool2源码走读(四) 对象池实现GenericObjectPool

    commons pool2源码走读 四 对象池实现GenericObjectPool