本文目录导读:

我来为你提供几个不同场景的Java对象池案例,从简单到复杂。
简单对象池实现(通用)
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
/**
* 通用对象池
*/
public class ObjectPool<T> {
private final BlockingQueue<T> pool;
private final Supplier<T> factory;
private final int maxSize;
private int createdCount = 0;
public ObjectPool(int maxSize, Supplier<T> factory) {
this.maxSize = maxSize;
this.factory = factory;
this.pool = new LinkedBlockingQueue<>(maxSize);
}
/**
* 从池中获取对象
*/
public T borrow() throws InterruptedException {
T obj = pool.poll();
if (obj == null) {
synchronized (this) {
if (createdCount < maxSize) {
obj = factory.get();
createdCount++;
}
}
if (obj == null) {
obj = pool.poll(5, TimeUnit.SECONDS);
}
}
return obj;
}
/**
* 归还对象到池中
*/
public void returnObject(T obj) {
if (obj != null) {
pool.offer(obj);
}
}
/**
* 池中可用对象数量
*/
public int availableCount() {
return pool.size();
}
}
数据库连接池示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
/**
* 数据库连接池
*/
public class DatabaseConnectionPool {
private static final Logger LOGGER = Logger.getLogger(DatabaseConnectionPool.class.getName());
private final String url;
private final String username;
private final String password;
private final int maxSize;
private final ConcurrentLinkedQueue<Connection> idleConnections;
private final AtomicInteger activeConnections = new AtomicInteger(0);
public DatabaseConnectionPool(String url, String username, String password, int maxSize) {
this.url = url;
this.username = username;
this.password = password;
this.maxSize = maxSize;
this.idleConnections = new ConcurrentLinkedQueue<>();
}
/**
* 获取数据库连接
*/
public Connection getConnection() throws SQLException {
Connection conn = idleConnections.poll();
if (conn == null && activeConnections.get() < maxSize) {
// 尝试创建新连接
synchronized (this) {
if (activeConnections.get() < maxSize) {
conn = createConnection();
activeConnections.incrementAndGet();
}
}
}
if (conn == null) {
// 等待其他连接被释放
long timeout = 5000; // 5秒超时
long startTime = System.currentTimeMillis();
while (conn == null && System.currentTimeMillis() - startTime < timeout) {
conn = idleConnections.poll();
if (conn == null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
}
if (conn == null) {
throw new SQLException("Connection pool exhausted, timeout waiting for connection");
}
// 验证连接是否有效
if (!isValid(conn)) {
closeConnection(conn);
return getConnection(); // 递归获取新连接
}
return conn;
}
/**
* 归还数据库连接
*/
public void returnConnection(Connection conn) {
if (conn != null) {
if (isValid(conn)) {
idleConnections.offer(conn);
} else {
closeConnection(conn);
activeConnections.decrementAndGet();
}
}
}
/**
* 关闭连接池
*/
public void shutdown() {
idleConnections.forEach(this::closeConnection);
idleConnections.clear();
activeConnections.set(0);
}
private Connection createConnection() throws SQLException {
Connection conn = DriverManager.getConnection(url, username, password);
// 启用自动提交
conn.setAutoCommit(true);
LOGGER.info("Created new database connection, total: " + activeConnections.get() + 1);
return conn;
}
private boolean isValid(Connection conn) {
try {
return conn != null && !conn.isClosed() && conn.isValid(3);
} catch (SQLException e) {
return false;
}
}
private void closeConnection(Connection conn) {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
LOGGER.severe("Error closing connection: " + e.getMessage());
}
}
}
使用示例 - 连接池客户端
public class DatabaseConnectionPoolDemo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydb";
String username = "root";
String password = "password";
// 创建连接池,最大5个连接
DatabaseConnectionPool pool = new DatabaseConnectionPool(url, username, password, 5);
// 多线程使用连接池
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executor.submit(() -> {
Connection conn = null;
try {
// 获取连接
conn = pool.getConnection();
// 执行数据库操作
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
while (rs.next()) {
// 处理结果...
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 归还连接
if (conn != null) {
pool.returnConnection(conn);
}
}
});
}
executor.shutdown();
// 关闭连接池
pool.shutdown();
}
}
基于Apache Commons Pool2的高级示例
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import java.time.Duration;
/**
* 使用Apache Commons Pool 2实现对象池
*/
public class AdvancedObjectPoolExample {
// 模拟一个昂贵的资源对象
public static class ExpensiveResource {
private final String resourceId;
private boolean inUse = false;
public ExpensiveResource() {
// 模拟创建成本
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
this.resourceId = "Resource-" + System.currentTimeMillis();
System.out.println("Created new resource: " + resourceId);
}
public String getResourceId() {
return resourceId;
}
public void doWork(String task) {
System.out.println(resourceId + " processing: " + task);
// 模拟工作
try {
Thread.sleep(50);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public void reset() {
System.out.println(resourceId + " resetting state");
this.inUse = false;
}
}
/**
* 对象池工厂
*/
public static class ResourceFactory extends BasePooledObjectFactory<ExpensiveResource> {
@Override
public ExpensiveResource create() throws Exception {
return new ExpensiveResource();
}
@Override
public PooledObject<ExpensiveResource> wrap(ExpensiveResource resource) {
return new DefaultPooledObject<>(resource);
}
@Override
public void activateObject(PooledObject<ExpensiveResource> p) throws Exception {
// 对象被借出时调用
p.getObject().inUse = true;
}
@Override
public void passivateObject(PooledObject<ExpensiveResource> p) throws Exception {
// 对象被归还时调用
p.getObject().inUse = false;
}
@Override
public void destroyObject(PooledObject<ExpensiveResource> p) throws Exception {
// 对象被销毁时调用
System.out.println("Destroying resource: " + p.getObject().getResourceId());
}
@Override
public boolean validateObject(PooledObject<ExpensiveResource> p) {
// 验证对象是否有效
return p.getObject() != null;
}
}
public static void main(String[] args) throws Exception {
// 配置对象池
GenericObjectPoolConfig<ExpensiveResource> config = new GenericObjectPoolConfig<>();
config.setMaxTotal(10); // 最大对象数
config.setMaxIdle(5); // 最大空闲对象数
config.setMinIdle(2); // 最小空闲对象数
config.setMaxWait(Duration.ofSeconds(5)); // 最大等待时间
config.setBlockWhenExhausted(true); // 池耗尽时阻塞
// 创建对象池
GenericObjectPool<ExpensiveResource> pool = new GenericObjectPool<>(new ResourceFactory(), config);
pool.setTestOnBorrow(true); // 借出时验证
pool.setTestOnReturn(true); // 归还时验证
// 预热对象池
pool.preparePool();
System.out.println("Initial idle objects: " + pool.getNumIdle());
System.out.println("Initial active objects: " + pool.getNumActive());
// 使用对象
try (ExpensiveResource resource = pool.borrowObject()) {
resource.doWork("Task 1");
} // try-with-resources 自动归还,但需要实现AutoCloseable
// 或者手动归还
ExpensiveResource resource = pool.borrowObject();
try {
resource.doWork("Task 2");
// 业务逻辑...
} finally {
pool.returnObject(resource);
}
// 并发使用
ExecutorService executor = Executors.newFixedThreadPool(15);
for (int i = 0; i < 15; i++) {
final int taskId = i;
executor.submit(() -> {
try {
ExpensiveResource r = pool.borrowObject();
try {
r.doWork("Concurrent Task " + taskId);
} finally {
pool.returnObject(r);
}
} catch (Exception e) {
e.printStackTrace();
}
});
}
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
// 统计信息
System.out.println("Pool statistics:");
System.out.println(" Active: " + pool.getNumActive());
System.out.println(" Idle: " + pool.getNumIdle());
System.out.println(" Created: " + pool.getCreatedCount());
// 关闭池
pool.close();
}
}
现代实现建议
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* 泛型对象池,支持函数式接口
*/
public class GenericObjectPool<T> {
private final ConcurrentLinkedDeque<PooledObject<T>> available = new ConcurrentLinkedDeque<>();
private final AtomicInteger created = new AtomicInteger(0);
private final int maxSize;
private final Function<Void, T> factory;
private final Consumer<T> resetFunction;
private static class PooledObject<T> {
final T object;
boolean inUse;
PooledObject(T object) {
this.object = object;
}
}
public GenericObjectPool(int maxSize, Function<Void, T> factory, Consumer<T> resetFunction) {
this.maxSize = maxSize;
this.factory = factory;
this.resetFunction = resetFunction;
}
/**
* 使用完后自动归还
*/
public <R> R execute(Function<T, R> action) throws Exception {
T obj = borrow();
try {
return action.apply(obj);
} finally {
if (obj != null) {
returnObject(obj);
}
}
}
private T borrow() throws Exception {
// 尝试从代池获取
PooledObject<T> pooledObj = available.poll();
if (pooledObj != null) {
return pooledObj.object;
}
// 创建新对象
if (created.get() < maxSize) {
synchronized (this) {
if (created.get() < maxSize) {
T obj = factory.apply(null);
created.incrementAndGet();
return obj;
}
}
}
// 等待有对象归还
while (true) {
pooledObj = available.poll();
if (pooledObj != null) {
return pooledObj.object;
}
Thread.sleep(1); // 简单等待
}
}
private void returnObject(T obj) {
if (obj != null) {
if (resetFunction != null) {
try {
resetFunction.accept(obj);
} catch (Exception e) {
// 重置失败,考虑销毁对象
return;
}
}
available.offer(new PooledObject<>(obj));
}
}
// 使用示例
public static void main(String[] args) throws Exception {
GenericObjectPool<StringBuilder> pool = new GenericObjectPool<>(
5,
v -> new StringBuilder(1024),
sb -> sb.setLength(0) // 重置内容
);
// 使用
String result = pool.execute(sb -> {
sb.append("Hello");
sb.append(" World");
return sb.toString();
});
System.out.println(result);
}
}
最佳实践建议
- 选择合适的池化框架:Apache Commons Pool 2 或 HikariCP 是成熟的选择
- 设置合理的池大小:太大会浪费资源,太小会影响性能
- 实现对象验证:确保归还的对象是可用的
- 处理对象创建失败:实现重试机制
- 监控池状态:记录池的使用情况和性能指标
- 考虑使用try-with-resources:确保对象正确归还
- 实现池预热:在应用启动时预创建一些对象
对象池的主要目的是提高性能,特别是当对象创建成本高时(如数据库连接、网络连接、线程等),在实现时要特别注意线程安全和异常处理。