Java GenericObjectPool 对象池化技术--SpringBoot sftp 连接池工具类

一个对象池包含一组已经初始化过且可以使用的对象,而可以在有需求时创建和销毁对象。池的用户可以从池子中取得对象,对其进行操作处理,并在不需要时归还给池子而非直接销毁它。这是一种特殊的工厂对象。



点击查看 MQTT(EMQX) - SpringBoot 创建 mqtt 连接池

点击查看 MQTT(EMQX) - SpringBoot 整合MQTT Demo - 附源代码



BasePooledObjectFactory 对象池化技术 的使用

Pom.xml

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.7.0</version>
</dependency>

MqttConnection.java

package com.vipsoft.mqtt.pool;

public class MqttConnection {

    private String mqttClient;
; public MqttConnection(String mqttClient) {
this.mqttClient = mqttClient;
} public String getMqttClient() {
return mqttClient;
} public void setMqttClient(String mqttClient) {
this.mqttClient = mqttClient;
} /**
* 推送方法消息
*/
public void publish(String msg) throws Exception {
System.out.println("对象" + mqttClient + ":" + "执行任务" + msg);
} @Override
public String toString() {
return "MqttConnection{" + "id=" + mqttClient + '}';
} }

MqttConnectionFactory.java

package com.vipsoft.mqtt.pool;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.util.concurrent.atomic.AtomicInteger; public class MqttConnectionFactory extends BasePooledObjectFactory<MqttConnection> { private static final Logger logger = LoggerFactory.getLogger(MqttConnectionFactory.class); // AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减
private AtomicInteger counter = new AtomicInteger(); /**
* 在对象池中创建对象
*
* @return
* @throws Exception
*/
@Override
public MqttConnection create() throws Exception { // 实现线程安全避免在高并发的场景下出现clientId重复导致无法创建连接的情况
int count = this.counter.addAndGet(1);
MqttConnection mqttConnection = new MqttConnection("MqttConnection:" + count);
logger.info("在对象池中创建对象 {}", mqttConnection.toString());
return mqttConnection;
} /**
* common-pool2 中创建了 DefaultPooledObject 对象对对象池中对象进行的包装。
* 将我们自定义的对象放置到这个包装中,工具会统计对象的状态、创建时间、更新时间、返回时间、出借时间、使用时间等等信息进行统计
*
* @param mqttConnection
* @return
*/
@Override
public PooledObject<MqttConnection> wrap(MqttConnection mqttConnection) {
logger.info("封装默认返回类型 {}", mqttConnection.toString());
return new DefaultPooledObject<>(mqttConnection);
} /**
* 销毁对象
*
* @param p 对象池
* @throws Exception 异常
*/
@Override
public void destroyObject(PooledObject<MqttConnection> p) throws Exception {
logger.info("销毁对象 {}", p.getObject().getMqttClient());
super.destroyObject(p);
} /**
* 校验对象是否可用
*
* @param p 对象池
* @return 对象是否可用结果,boolean
*/
@Override
public boolean validateObject(PooledObject<MqttConnection> p) {
logger.info("校验对象是否可用 {}", p.getObject().getMqttClient());
return super.validateObject(p);
} /**
* 激活钝化的对象系列操作
*
* @param p 对象池
* @throws Exception 异常信息
*/
@Override
public void activateObject(PooledObject<MqttConnection> p) throws Exception {
logger.info("激活钝化的对象 {}", p.getObject().getMqttClient());
super.activateObject(p);
} /**
* 钝化未使用的对象
*
* @param p 对象池
* @throws Exception 异常信息
*/
@Override
public void passivateObject(PooledObject<MqttConnection> p) throws Exception {
logger.info("钝化未使用的对象 {}", p.getObject().getMqttClient());
super.passivateObject(p);
}
}

PoolTest.java

package com.vipsoft.mqtt;

import cn.hutool.core.date.DateUtil;
import com.vipsoft.mqtt.pool.MqttConnection;
import com.vipsoft.mqtt.pool.MqttConnectionFactory;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger; @SpringBootTest
public class PoolTest { @Test
void basePooledTest() throws InterruptedException { AtomicInteger atomicInteger = new AtomicInteger(); int excutorCount = 15;
CountDownLatch countDownLatch = new CountDownLatch(excutorCount); // =====================创建线程池=====================
ExecutorService excutor = Executors.newFixedThreadPool(5);
// =====================创建对象池=====================
// 对象池工厂
MqttConnectionFactory personPoolFactory = new MqttConnectionFactory();
// 对象池配置
GenericObjectPoolConfig<MqttConnection> objectPoolConfig = new GenericObjectPoolConfig<>();
objectPoolConfig.setMaxTotal(50);
// 对象池
GenericObjectPool<MqttConnection> mqttPool = new GenericObjectPool<>(personPoolFactory, objectPoolConfig);
// =====================测试对象池=====================
// 循环100次,从线程池中取多个多线程执行任务,来测试对象池
for (int i = 0; i < excutorCount; i++) {
excutor.submit(new Thread(() -> {
// 模拟从对象池取出对象,执行任务
MqttConnection mqtt = null;
try {
// 从对象池取出对象
mqtt = mqttPool.borrowObject();
// 让对象工作
int count = atomicInteger.addAndGet(1);
mqtt.publish("Id:" + count + " Time: " + DateUtil.now());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 回收对象到对象池
if (mqtt != null) {
mqttPool.returnObject(mqtt);
}
countDownLatch.countDown();
}
}));
}
countDownLatch.await();
}
}

Java BasePooledObjectFactory 对象池化技术的更多相关文章

  1. 对象池化技术 org.apache.commons.pool

    恰当地使用对象池化技术,可以有效地减少对象生成和初始化时的消耗,提高系统的运行效率.Jakarta Commons Pool组件提供了一整套用于实现对象池化的框架,以及若干种各具特色的对象池实现,可以 ...

  2. java对象池化技术

    https://blog.csdn.net/tiane5hao/article/details/85957840 文章目录 先写一个简单通用的对象池 通过上面的通用池实现jedis连接池 连接池测试 ...

  3. Java--对象池化技术 org.apache.commons.pool2.ObjectPool

    org.apache.commons.pool2.ObjectPool提供了对象池,开发的小伙伴们可以直接使用来构建一个对象池 使用该对象池具有两个简单的步骤: 1.创建对象工厂,org.apache ...

  4. Java 数据持久化系列之池化技术

    在上一篇文章<Java 数据持久化系列之JDBC>中,我们了解到使用 JDBC 创建 Connection 可以执行对应的SQL,但是创建 Connection 会消耗很多资源,所以 Ja ...

  5. commons-pool2 池化技术探究

    一.前言 我们经常会接触各种池化的技术或者概念,包括对象池.连接池.线程池等,池化技术最大的好处就是实现对象的重复利用,尤其是创建和使用大对象或者宝贵资源(HTTP连接对象,MySQL连接对象)等方面 ...

  6. Java之对象池

    单例模式是限制了一个类只能有一个实例,对象池模式则是限制一个类实例的个数.对象池类就像是一个对象管理员,它以Static列表(也就是装对象的池子)的形式存存储某个实例数受限的类的实例,每一个实例还要加 ...

  7. 《Mybatis 手撸专栏》第6章:数据源池化技术实现

    作者:小傅哥 博客:https://bugstack.cn - 手写Mybatis系列文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 码农,只会做不会说? 你有发现吗,其实很大一部分码农 ...

  8. CVPR 2019|PoolNet:基于池化技术的显著性检测 论文解读

    作者 | 文永亮 研究方向 | 目标检测.GAN 研究动机 ​ 这是一篇发表于CVPR2019的关于显著性目标检测的paper,在U型结构的特征网络中,高层富含语义特征捕获的位置信息在自底向上的传播过 ...

  9. 深度剖析C++对象池自动回收技术实现

    http://www.tuicool.com/articles/mQBfQfN 对象池可以显著提高性能,如果一个对象的创建非常耗时或非常昂贵,频繁去创建的话会非常低效.对象池通过对象复用的方式来避免重 ...

  10. [翻译] 编写高性能 .NET 代码--第二章 GC -- 将长生命周期对象和大对象池化

    将长生命周期对象和大对象池化 请记住最开始说的原则:对象要么立即回收要么一直存在.它们要么在0代被回收,要么在2代里一直存在.有些对象本质是静态的,生命周期从它们被创建开始,到程序停止才会结束.其它对 ...

随机推荐

  1. vue后台管理系统——用户管理模块

    电商后台管理系统的功能--用户管理模块 1. 用户管理概述 通过后台管理用户的账号信息,具体包括用户信息的展示.添加.修改.删除.角色分配.账号启用/注销等功能. 用户信息列表展示 添加用户 修改用户 ...

  2. Ubuntu系统运行Steam中VR游戏的相关软件环境配置说明

    ubuntu下的SteamVR(HTCVive)设置教程 贴吧链接     https://tieba.baidu.com/p/5333529880 运行SteamVR出现的一些问题解决方案参考链接  ...

  3. 添加新模块 import

    import getpass username = input("username") password = input("password") #passwo ...

  4. 笔记:map函数方法映射

    ------------恢复内容开始------------ map函数可以对后端接口返回一个数组 map存在一个参数时: map存在三个参数时: 语法: array.map(function(cur ...

  5. 了解windows下的npm

    之前一直使用Ubuntu系统,对于需要的软件.安装包,都可以使用apt或者apt-get进行安装,本人也是用过python,对于python库的安装,也可以通过pip或者conda来实现,那么,在wi ...

  6. git 报错 incorrect username or password

    如果报这个 就是用户名 或密码错误 添加个正确的凭据就好了

  7. yield基础知识

    function* y(p1){ let r=p1; r=(yield r-5) //表达式A,在第1轮是普通return,在第2轮next(param)时会被param替换 r=(yield r*2 ...

  8. 英国延长 UKCA 标记截止日期

    政府于 2022 年 11 月 14 日宣布,企业将有 2 年的时间来应用新的 UKCA 产品标记.在 2024 年 12 月 31 日之前,企业可以选择使用 UKCA 或 CE 标志,之后企业只能使 ...

  9. 【转载】Python 在已存在的excel表格中写入数据

    由于每天都要汇总日报数据,其实就是个复制粘贴的工作,将多个表的数据汇总成一个表格,工作较枯燥,于是想到用Python帮我完成这个简单又粗糙的工作.写一下我学到的几个小技巧,下次忘记怎么使用的时候,还能 ...

  10. Calendar 获取当前月份最后一周

    import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class Ca ...