模板网站多少钱,高端网站建设必去磐石网络,网站建设意见建议,张家口职教中心计算机网站建设概述
池化技术#xff0c;一种通过重复利用对象实例而非频繁创建和销毁的技术。
常见的可池化对象#xff1a;
数据库连接(Connection)#xff1a;数据库连接创建和销毁代价高#xff0c;连接池广泛用于管理JDBC连接#xff1b;线程(Thread)#xff1a;线程的创建和销…概述
池化技术一种通过重复利用对象实例而非频繁创建和销毁的技术。
常见的可池化对象
数据库连接(Connection)数据库连接创建和销毁代价高连接池广泛用于管理JDBC连接线程(Thread)线程的创建和销毁开销大线程池是多线程编程中常用的技术网络连接(Socket/HTTPClient)复用HTTP连接以提高网络通信效率对象实例(Object)对于短生命周期且频繁使用的对象可通过对象池管理其生命周期内存块或缓冲区(Buffer)I/O操作中经常使用缓冲池如Netty的ByteBuf池来减少内存分配和垃圾回收的开销会话或上下文对象(Session/Context)在Web应用或分布式系统中Session对象可通过池化优化访问性能。
具体的池化技术
数据库连接池如HikariCP、Druid、C3P0管理JDBC连接生命周期包括创建、复用和回收。线程池如Java中的ExecutorService和ThreadPoolExecutor。控制线程的并发量和资源使用避免频繁创建线程。HTTP连接池如OkHttp、Apache HttpClient。复用HTTP连接减少TCP连接开销。对象池如Apache Commons Pool、HikariCP的对象池管理。用于频繁创建和销毁的轻量级对象实例。缓冲区池如Netty的内存池ByteBufAllocator池化I/O缓冲区以减少垃圾回收的负担。GPU内存池如CUDA的内存池在深度学习或图像处理场景中复用显存资源。分布式对象池如Redisson对Redis资源的池化封装管理分布式系统中的共享资源。
当遇到以下场景可考虑使用池化技术来提高系统性能
对象的创建或销毁很频繁需要使用较多的系统资源如数据库连接、线程、HTTP请求生命周期较短且重复使用的对象如临时计算对象、缓冲区需要高并发和低延迟如Web服务、实时数据流处理资源昂贵的操作如GPU显存管理、大型文件处理。
优势
减少资源开销通过复用降低对象的创建和销毁成本提高性能更快的响应时间和更少的垃圾回收降低复杂度池化工具通常内置优化策略如负载均衡、超时管理。
注意事项
资源竞争池的大小配置过小可能导致资源争抢过大则浪费资源池中对象管理需要避免对象泄漏或资源未正确释放过期资源处理池化资源可能因为网络或连接原因失效需实现健康检查和自动回收。
线程池
参考面试必备之线程池(Java)以及ForkJoinPool以及MySQL线程池。
连接池
参考JDBC与数据库连接池。
缓冲池
MySQL提供缓冲池能力待学习。
对象池
提到对象池不得不说ApacheGitHub的Commons Pool。
官方文档
核心组件(API)
对象池(ObjectPool)实现对对象存取和状态管理的池实现如线程池、数据库连接池池化对象(PooledObject)池化对象放在ObjectPool里的包装类。添加一些附加信息如状态创建时间激活时间关闭时间等池化对象工厂(PooledObjectFactory)工厂类负责具体对象的创建、初始化、销毁和状态验证。
关系图
实战
引入如下依赖
dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactIdversion2.12.0/version
/dependency实现一个简单的数据库连接池
AllArgsConstructor
public class DatabaseConnectionFactory extends BasePooledObjectFactoryConnection {private String connectionString;private String username;private String password;// 创建新的数据库连接Overridepublic Connection create() {try {return DriverManager.getConnection(connectionString, username, password);} catch (SQLException e) {throw new RuntimeException(创建数据库连接失败, e);}}// 销毁数据库连接Overridepublic void destroyObject(PooledObjectConnection p) throws Exception {p.getObject().close();}// 验证数据库连接是否有效Overridepublic boolean validateObject(PooledObjectConnection p) {try {return p.getObject().isValid(1); // 设置一个非常短的超时仅用于检查连接是否仍然可用} catch (SQLException e) {return false;}}// 激活对象可选No-opOverridepublic void activateObject(PooledObjectConnection p) throws Exception {// 可在这里进行一些连接重新激活的操作例如设置自动提交、隔离级别等}// 钝化对象可选No-opOverridepublic void passivateObject(PooledObjectConnection p) throws Exception {// 可在对象返回到池之前执行一些清理或重置操作}
}配置和创建ObjectPool
public class DatabaseConnectionPool {private static GenericObjectPoolConnection pool;static {// 配置连接池的参数GenericObjectPoolConfig config new GenericObjectPoolConfig();config.setMaxTotal(10); // 设置连接池的最大连接数config.setMaxIdle(5); // 设置连接池的最大空闲连接数config.setMinIdle(2); // 设置连接池的最小空闲连接数DatabaseConnectionFactory factory new DatabaseConnectionFactory(jdbc:mysql://localhost:3306/mydatabase, user, password);// 初始化连接池pool new GenericObjectPool(factory, config);}// 获取数据库连接public static Connection getConnection() throws Exception {return pool.borrowObject();}// 归还数据库连接到池public static void releaseConnection(Connection conn) {if (conn ! null) {pool.returnObject(conn);}}// 关闭连接池通常在应用程序关闭时调用public static void close() {if (pool ! null) {pool.close();}}
}最后是测试类
public static void main(String[] args) {try (Connection conn DatabaseConnectionPool.getConnection()) {// 使用连接执行数据库操作 // 连接会在try-with-resources块结束时自动归还到池中} catch (Exception e) {// log}// 注意在应用程序结束时应该调用DatabaseConnectionPool.close()来关闭连接池
}原理
大致如下图 注
minEvictableldleTimeMillis是早期版本的拼写最新版2.12.0对应的参数是minEvictableIdleDurationsoftMinEvictableldleTimeMillis对应的参数是softMinEvictableIdleDurationtimeBetweenEvictionRunsMillis对应的参数是durationBetweenEvictionRuns。
4个test参数
testOnCreate指定在创建时是否对池化对象进行有效性检测以下类似testOnBorrow获取testOnReturn归还testWhileIdle空闲检测
生产环境建议只将testWhileIdle设置为true其他几个参数设置为false并通过调整空闲检测时间间隔(timeBetweenEvictionRunsMillisdurationBetweenEvictionRuns)来保证资源的可用性和效率。
源码
ObjectPool
public interface ObjectPoolT extends Closeable {// 添加对象void addObject() throws Exception;// 添加多个对象default void addObjects(final int count) throws Exception {for (int i 0; i count; i) {addObject();}}// 从池中获取对象T borrowObject() throws Exception;// 清除池池可用void clear() throws Exception;// 关闭池池不可用Overridevoid close();// 获取活跃对象个数int getNumActive();// 获取空闲对象个数int getNumIdle();// 废弃对象void invalidateObject(T obj) throws Exception;// 使用指定的废弃模式废弃对象default void invalidateObject(final T obj, final DestroyMode destroyMode) throws Exception {invalidateObject(obj);}// 将对象放回池中void returnObject(T obj) throws Exception;
}枚举类DestroyMode源码如下
public enum DestroyMode {// 常规废弃NORMAL,// Destroy abandoned objectABANDONED
}PooledObject
public interface PooledObjectT extends ComparablePooledObjectT {static boolean isNull(final PooledObject? pooledObject) {return pooledObject null || pooledObject.getObject() null;}boolean allocate();boolean deallocate();boolean endEvictionTest(DequePooledObjectT idleQueue);default Duration getActiveDuration() {// Take copies to avoid threading issuesfinal Instant lastReturnInstant getLastReturnInstant();final Instant lastBorrowInstant getLastBorrowInstant();// formatter:offreturn lastReturnInstant.isAfter(lastBorrowInstant) ?Duration.between(lastBorrowInstant, lastReturnInstant) :Duration.between(lastBorrowInstant, Instant.now());// formatter:on}Deprecateddefault Duration getActiveTime() {return getActiveDuration();}Deprecatedlong getActiveTimeMillis();default long getBorrowedCount() {return -1;}default Instant getCreateInstant() {return Instant.ofEpochMilli(getCreateTime());}Deprecatedlong getCreateTime();default Duration getFullDuration() {return Duration.between(getCreateInstant(), Instant.now());}default Duration getIdleDuration() {return Duration.ofMillis(getIdleTimeMillis());}Deprecateddefault Duration getIdleTime() {return Duration.ofMillis(getIdleTimeMillis());}Deprecatedlong getIdleTimeMillis();default Instant getLastBorrowInstant() {return Instant.ofEpochMilli(getLastBorrowTime());}Deprecatedlong getLastBorrowTime();default Instant getLastReturnInstant() {return Instant.ofEpochMilli(getLastReturnTime());}Deprecatedlong getLastReturnTime();default Instant getLastUsedInstant() {return Instant.ofEpochMilli(getLastUsedTime());}Deprecatedlong getLastUsedTime();T getObject();PooledObjectState getState();void invalidate();void markAbandoned();void markReturning();void printStackTrace(PrintWriter writer);void setLogAbandoned(boolean logAbandoned);default void setRequireFullStackTrace(final boolean requireFullStackTrace) {// noop}boolean startEvictionTest();void use();Overrideint compareTo(PooledObjectT other);Overrideboolean equals(Object obj); Overrideint hashCode();String toString();
}PooledObjectFactory泛型接口
public interface PooledObjectFactoryT {void activateObject(PooledObjectT p) throws Exception;void destroyObject(PooledObjectT p) throws Exception;default void destroyObject(final PooledObjectT p, final DestroyMode destroyMode) throws Exception {destroyObject(p);}PooledObjectT makeObject() throws Exception;void passivateObject(PooledObjectT p) throws Exception;boolean validateObject(PooledObjectT p);
}解读
makeObject创建一个新对象当对象池中的对象个数不足个数配置参考下面的Config时将会使用此方法来产生一个新的对象并交付给对象池管理destroyObject销毁对象如果检测到对象池中某个对象idle的时间超时或操作者向对象池归还对象时检测到对象已经无效则触发对象销毁。调用此方法时对象的生命周期必须结束。如果object是线程则线程必须退出如果是Socket操作则Socket必须关闭如果是文件流操作则此时数据flush且正常关闭。validateObject检测对象是否有效Pool中不能保存无效的对象因此后台检测线程会周期性的检测Pool中对象的有效性如果对象无效则会导致此对象从Pool中移除并destroy此外在调用者从Pool获取一个对象时也会检测对象的有效性确保不会将无效的对象输出给调用者当调用者使用完毕将对象归还到Pool时仍然会检测对象的有效性。有效性就是此对象的状态是否符合预期调用者是否可直接使用如果对象是Socket有效性则意味着Socket的通道是否畅通/阻塞是否超时等。activateObject激活对象当Pool中决定移除一个对象交付给调用者时额外的激活操作比如可在activateObject方法中重置参数列表让调用者使用时感觉像一个新创建的对象一样。如果object是线程可在激活操作中重置线程中断标记或让线程从阻塞中唤醒等如果是Socket则可在激活操作中刷新通道或对Socket进行连接重建假如Socket意外关闭等。passivateObject钝化对象当调用者归还对象时Pool将会钝化对象。如果object是Socket则清除buffer将Socket阻塞如果是线程可在钝化操作中将线程sleep或将线程中的某个对象wait。activateObject和passivateObject两个方法需要一一对应避免死锁或对象状态的混乱。
BaseObjectPoolConfig提供的配置
lifo连接池放池化对象方式默认为truetrue放在空闲队列最前面false放在空闲队列最后面fairness等待线程拿空闲连接的方式默认为falsetrue相当于等待线程是在先进先出去拿空闲连接maxWaitMillis当连接池资源耗尽时调用者最大阻塞的时间超时将抛出异常。单位为毫秒数默认为-1表示永不超时。已废弃请使用maxWaitDurationminEvictableIdleTimeMillis连接空闲的最小时间达到此值后空闲连接将可能会被移除。负值(-1)表示不移除默认值1000L 60L 30L。已废弃请使用minEvictableIdleDurationsoftMinEvictableIdleTimeMillis连接空闲的最小时间达到此值后空闲连接将会被移除且保留minIdle个空闲连接数。已废弃请使用softMinEvictableIdleDurationnumTestsPerEvictionRun对于空闲连接检测线程而言每次检测的连接资源的个数。默认值3evictionPolicyClassName默认值org.apache.commons.pool2.impl.DefaultEvictionPolicytestOnCreate默认值falsetestOnBorrow向调用者输出连接资源时是否检测是有有效如果无效则从连接池中移除并尝试获取继续获取。默认为false。建议保持默认值testOnReturn默认值falsetestWhileIdle向调用者输出连接对象时是否检测它的空闲超时默认为false。如果连接空闲超时将会被移除建议保持默认值。默认值falsetimeBetweenEvictionRunsMillis空闲连接检测线程检测周期单位是毫秒数。如果为负值表示不运行检测线程。默认值为-1。已废弃请使用durationBetweenEvictionRunsdurationBetweenEvictionRunsblockWhenExhausted默认值truejmxEnabled默认值truejmxNamePrefix默认值pooljmxNameBase默认值nullmaxTotal连接池中最大连接数
参考