parent
ffe1f13b1f
commit
2bdebdbac0
@ -0,0 +1,196 @@
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue