Java?BasePooledObjectFactory?對象池化技術(shù)的使用
Java GenericObjectPool 對象池化技術(shù)--SpringBoot sftp 連接池工具類
一個對象池包含一組已經(jīng)初始化過且可以使用的對象,而可以在有需求時創(chuàng)建和銷毀對象。池的用戶可以從池子中取得對象,對其進行操作處理,并在不需要時歸還給池子而非直接銷毀它。這是一種特殊的工廠對象。
BasePooledObjectFactory 對象池化技術(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("對象" + 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是一個提供原子操作的Integer類,通過線程安全的方式操作加減 private AtomicInteger counter = new AtomicInteger(); /** * 在對象池中創(chuàng)建對象 * * @return * @throws Exception */ @Override public MqttConnection create() throws Exception { // 實現(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("在對象池中創(chuàng)建對象 {}", mqttConnection.toString()); return mqttConnection; } /** * common-pool2 中創(chuàng)建了 DefaultPooledObject 對象對對象池中對象進行的包裝。 * 將我們自定義的對象放置到這個包裝中,工具會統(tǒng)計對象的狀態(tài)、創(chuàng)建時間、更新時間、返回時間、出借時間、使用時間等等信息進行統(tǒng)計 * * @param mqttConnection * @return */ @Override public PooledObject<MqttConnection> wrap(MqttConnection mqttConnection) { logger.info("封裝默認(rèn)返回類型 {}", 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 對象是否可用結(jié)果,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); // =====================創(chuàng)建線程池===================== ExecutorService excutor = Executors.newFixedThreadPool(5); // =====================創(chuàng)建對象池 項目中使用了InitializingBean.afterPropertiesSet() 中創(chuàng)建===================== // 對象池工廠 MqttConnectionFactory personPoolFactory = new MqttConnectionFactory(); // 對象池配置 GenericObjectPoolConfig<MqttConnection> objectPoolConfig = new GenericObjectPoolConfig<>(); objectPoolConfig.setMaxTotal(50); // 對象池 GenericObjectPool<MqttConnection> mqttPool = new GenericObjectPool<>(personPoolFactory, objectPoolConfig); // =====================測試對象池===================== // 循環(huán)100次,從線程池中取多個多線程執(zhí)行任務(wù),來測試對象池 for (int i = 0; i < excutorCount; i++) { excutor.submit(new Thread(() -> { // 模擬從對象池取出對象,執(zhí)行任務(wù) 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(); } }
到此這篇關(guān)于Java BasePooledObjectFactory 對象池化技術(shù)的文章就介紹到這了,更多相關(guān)Java 對象池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用synchronized實現(xiàn)互斥鎖功能示例
這篇文章主要介紹了Java使用synchronized實現(xiàn)互斥鎖功能,結(jié)合實例形式分析了Java使用synchronized互斥鎖功能簡單實現(xiàn)方法與操作技巧,需要的朋友可以參考下2020-05-05Java 基礎(chǔ) byte[]與各種數(shù)據(jù)類型互相轉(zhuǎn)換的簡單示例
這篇文章主要介紹了Java 基礎(chǔ) byte[]與各種數(shù)據(jù)類型互相轉(zhuǎn)換的簡單示例的相關(guān)資料,這里對byte[]類型對long,int,double,float,short,cahr,object,string類型相互轉(zhuǎn)換的實例,需要的朋友可以參考下2017-01-01如何基于SpringWeb?MultipartFile實現(xiàn)文件上傳、下載功能
在做項目時,后端經(jīng)常采用上傳文件組件MultipartFile,下面這篇文章主要給大家介紹了關(guān)于如何基于SpringWeb?MultipartFile實現(xiàn)文件上傳、下載功能的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07SpringBoot中的server.context-path的實現(xiàn)
本文主要介紹了SpringBoot中的server.context-path的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08