Java?BasePooledObjectFactory?對(duì)象池化技術(shù)的使用
Java GenericObjectPool 對(duì)象池化技術(shù)--SpringBoot sftp 連接池工具類
一個(gè)對(duì)象池包含一組已經(jīng)初始化過且可以使用的對(duì)象,而可以在有需求時(shí)創(chuàng)建和銷毀對(duì)象。池的用戶可以從池子中取得對(duì)象,對(duì)其進(jìn)行操作處理,并在不需要時(shí)歸還給池子而非直接銷毀它。這是一種特殊的工廠對(duì)象。
BasePooledObjectFactory 對(duì)象池化技術(shù)的使用

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("對(duì)象" + mqttClient + ":" + "執(zhí)行任務(wù)" + 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是一個(gè)提供原子操作的Integer類,通過線程安全的方式操作加減
private AtomicInteger counter = new AtomicInteger();
/**
* 在對(duì)象池中創(chuàng)建對(duì)象
*
* @return
* @throws Exception
*/
@Override
public MqttConnection create() throws Exception {
// 實(shí)現(xiàn)線程安全避免在高并發(fā)的場景下出現(xiàn)clientId重復(fù)導(dǎo)致無法創(chuàng)建連接的情況
int count = this.counter.addAndGet(1);
MqttConnection mqttConnection = new MqttConnection("MqttConnection:" + count);
logger.info("在對(duì)象池中創(chuàng)建對(duì)象 {}", mqttConnection.toString());
return mqttConnection;
}
/**
* common-pool2 中創(chuàng)建了 DefaultPooledObject 對(duì)象對(duì)對(duì)象池中對(duì)象進(jìn)行的包裝。
* 將我們自定義的對(duì)象放置到這個(gè)包裝中,工具會(huì)統(tǒng)計(jì)對(duì)象的狀態(tài)、創(chuàng)建時(shí)間、更新時(shí)間、返回時(shí)間、出借時(shí)間、使用時(shí)間等等信息進(jìn)行統(tǒng)計(jì)
*
* @param mqttConnection
* @return
*/
@Override
public PooledObject<MqttConnection> wrap(MqttConnection mqttConnection) {
logger.info("封裝默認(rèn)返回類型 {}", mqttConnection.toString());
return new DefaultPooledObject<>(mqttConnection);
}
/**
* 銷毀對(duì)象
*
* @param p 對(duì)象池
* @throws Exception 異常
*/
@Override
public void destroyObject(PooledObject<MqttConnection> p) throws Exception {
logger.info("銷毀對(duì)象 {}", p.getObject().getMqttClient());
super.destroyObject(p);
}
/**
* 校驗(yàn)對(duì)象是否可用
*
* @param p 對(duì)象池
* @return 對(duì)象是否可用結(jié)果,boolean
*/
@Override
public boolean validateObject(PooledObject<MqttConnection> p) {
logger.info("校驗(yàn)對(duì)象是否可用 {}", p.getObject().getMqttClient());
return super.validateObject(p);
}
/**
* 激活鈍化的對(duì)象系列操作
*
* @param p 對(duì)象池
* @throws Exception 異常信息
*/
@Override
public void activateObject(PooledObject<MqttConnection> p) throws Exception {
logger.info("激活鈍化的對(duì)象 {}", p.getObject().getMqttClient());
super.activateObject(p);
}
/**
* 鈍化未使用的對(duì)象
*
* @param p 對(duì)象池
* @throws Exception 異常信息
*/
@Override
public void passivateObject(PooledObject<MqttConnection> p) throws Exception {
logger.info("鈍化未使用的對(duì)象 {}", 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);
// =====================創(chuàng)建線程池=====================
ExecutorService excutor = Executors.newFixedThreadPool(5);
// =====================創(chuàng)建對(duì)象池 項(xiàng)目中使用了InitializingBean.afterPropertiesSet() 中創(chuàng)建=====================
// 對(duì)象池工廠
MqttConnectionFactory personPoolFactory = new MqttConnectionFactory();
// 對(duì)象池配置
GenericObjectPoolConfig<MqttConnection> objectPoolConfig = new GenericObjectPoolConfig<>();
objectPoolConfig.setMaxTotal(50);
// 對(duì)象池
GenericObjectPool<MqttConnection> mqttPool = new GenericObjectPool<>(personPoolFactory, objectPoolConfig);
// =====================測試對(duì)象池=====================
// 循環(huán)100次,從線程池中取多個(gè)多線程執(zhí)行任務(wù),來測試對(duì)象池
for (int i = 0; i < excutorCount; i++) {
excutor.submit(new Thread(() -> {
// 模擬從對(duì)象池取出對(duì)象,執(zhí)行任務(wù)
MqttConnection mqtt = null;
try {
// 從對(duì)象池取出對(duì)象
mqtt = mqttPool.borrowObject();
// 讓對(duì)象工作
int count = atomicInteger.addAndGet(1);
mqtt.publish("Id:" + count + " Time: " + DateUtil.now());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 回收對(duì)象到對(duì)象池
if (mqtt != null) {
mqttPool.returnObject(mqtt);
}
countDownLatch.countDown();
}
}));
}
countDownLatch.await();
}
}

到此這篇關(guān)于Java BasePooledObjectFactory 對(duì)象池化技術(shù)的文章就介紹到這了,更多相關(guān)Java 對(duì)象池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java延時(shí)的3種實(shí)現(xiàn)方法舉例
這篇文章主要給大家介紹了關(guān)于Java延時(shí)的3種實(shí)現(xiàn)方法舉例,java開發(fā)中常會(huì)用到延時(shí)任務(wù),文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)具有一定參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
Java實(shí)現(xiàn)自定義Excel數(shù)據(jù)排序的方法詳解
通常,我們可以在Excel中對(duì)指定列數(shù)據(jù)執(zhí)行升序或者降序排序,在需要自定義排序情況下,我們也可以自行根據(jù)排序需要編輯數(shù)據(jù)排列順序。本文將通過Java應(yīng)用程序來實(shí)現(xiàn)如何自定義排序,需要的可以參考一下2022-09-09
SpringBootTest報(bào)錯(cuò)的問題解決
本文主要介紹了SpringBootTest報(bào)錯(cuò)的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-09-09
SpringBoot詳細(xì)分析自動(dòng)裝配原理并實(shí)現(xiàn)starter
相對(duì)于傳統(tǒng)意義上的Spring項(xiàng)目,SpringBoot具有開箱即用,簡化配置,內(nèi)置Tomcat等等等等一系列的特點(diǎn)。在這些特點(diǎn)中,最重要的兩條就是約定優(yōu)于配置和自動(dòng)裝配2022-07-07

