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
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();
|
|
}
|
|
}
|
|
} |