You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
5.3 KiB

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Object pool manager: Responsible for DatabaseConnection creation, reuse, and recycling
* @author chuyang
* @version 1.0
*/
public class ConnectionPoolManager {
/**
* Connection pool storage
*/
private final List<DatabaseConnection> connectionPool;
/**
* Database URL
*/
private final String databaseUrl;
/**
* Initial pool size
*/
private final int initialSize;
/**
* Maximum pool size
*/
private final int maxSize;
/**
* For thread safety
*/
private final Lock poolLock = new ReentrantLock();
public DatabaseConnection m_DatabaseConnection;
public ConnectionPoolManager(){
this.connectionPool = new ArrayList<>();
this.databaseUrl = "";
this.initialSize = 0;
this.maxSize = 0;
}
@Override
public void finalize() throws Throwable {
// Close all connections
poolLock.lock();
try {
for (DatabaseConnection conn : connectionPool) {
System.out.println("Closing connection " + conn.getConnectionId());
}
connectionPool.clear();
} finally {
poolLock.unlock();
}
}
/**
* Constructor: Initialize object pool
*
* @param initialSize Initial number of connections
* @param maxSize Maximum number of connections
* @param databaseUrl Database URL
*/
public ConnectionPoolManager(int initialSize, int maxSize, String databaseUrl){
if (initialSize < 0 || maxSize < initialSize) {
throw new IllegalArgumentException("Invalid pool size parameters");
}
this.connectionPool = new ArrayList<>(maxSize);
this.databaseUrl = databaseUrl;
this.initialSize = initialSize;
this.maxSize = maxSize;
// Initialize connection pool
initializePool();
}
/**
* Initialize the connection pool, create initial connections
*/
private void initializePool() {
System.out.println("Initializing connection pool with " + initialSize + " connections");
for (int i = 0; i < initialSize; i++) {
String connId = "conn-" + i;
DatabaseConnection conn = new DatabaseConnection(connId, databaseUrl);
connectionPool.add(conn);
}
System.out.println("Connection pool initialized with " + connectionPool.size() + " connections");
}
/**
* Borrow a connection from the pool
* @return Available connection, or null (pool is full)
*/
public DatabaseConnection borrowConnection(){
poolLock.lock();
try {
// 1. Look for idle connection
for (DatabaseConnection conn : connectionPool) {
if (!conn.isInUse()) {
conn.setInUse(true);
System.out.println("Borrowed existing connection: " + conn.getConnectionId());
return conn;
}
}
// 2. If no idle connections and max size not reached, create new connection
if (connectionPool.size() < maxSize) {
String connId = "conn-" + connectionPool.size();
DatabaseConnection newConn = new DatabaseConnection(connId, databaseUrl);
newConn.setInUse(true);
connectionPool.add(newConn);
System.out.println("Created and borrowed new connection: " + newConn.getConnectionId());
return newConn;
}
// 3. Pool is full, return null
System.out.println("Connection pool is full, no available connections");
return null;
} finally {
poolLock.unlock();
}
}
/**
* Return connection to the pool
*
* @param conn Connection to return
*/
public void returnConnection(DatabaseConnection conn){
if (conn == null) {
return;
}
poolLock.lock();
try {
// Check if connection belongs to this pool
if (connectionPool.contains(conn)) {
// Reset connection state
conn.reset();
conn.setInUse(false);
System.out.println("Connection returned to pool: " + conn.getConnectionId());
} else {
System.out.println("Warning: Attempting to return a connection not managed by this pool");
}
} finally {
poolLock.unlock();
}
}
/**
* Shrink pool: Destroy idle connections
*/
public void shrinkPool(){
poolLock.lock();
try {
// Only keep initial size of connections
List<DatabaseConnection> connectionsToRemove = new ArrayList<>();
int activeConnections = 0;
for (DatabaseConnection conn : connectionPool) {
if (conn.isInUse()) {
activeConnections++;
} else if (connectionPool.size() - connectionsToRemove.size() > initialSize) {
connectionsToRemove.add(conn);
System.out.println("Removing idle connection: " + conn.getConnectionId());
}
}
connectionPool.removeAll(connectionsToRemove);
System.out.println("Pool shrunk. Active connections: " + activeConnections + ", Idle connections: " + connectionPool.size() + ", Removed: " + connectionsToRemove.size());
} finally {
poolLock.unlock();
}
}
/**
* Get pool status information
*/
public String getPoolStatus() {
poolLock.lock();
try {
int activeConnections = 0;
for (DatabaseConnection conn : connectionPool) {
if (conn.isInUse()) {
activeConnections++;
}
}
return "Pool status: " + connectionPool.size() + " total connections, " +
activeConnections + " active, " +
(connectionPool.size() - activeConnections) + " idle, " +
"Max capacity: " + maxSize;
} finally {
poolLock.unlock();
}
}
}