A Simple Guide to Connection Pooling in Java
一篇關(guān)于Java連接池指導(dǎo),個人比較關(guān)注是實(shí)現(xiàn)一個簡單連接池內(nèi)容。
文章提供一段連接池的代碼
public class BasicConnectionPool
implements ConnectionPool {
private String url;
private String user;
private String password;
private List<Connection> connectionPool;
private List<Connection> usedConnections = new ArrayList<>();
private static int INITIAL_POOL_SIZE = 10;
public static BasicConnectionPool create(
String url, String user,
String password) throws SQLException {
List<Connection> pool = new ArrayList<>(INITIAL_POOL_SIZE);
for (int i = 0; i < INITIAL_POOL_SIZE; i++) {
pool.add(createConnection(url, user, password));
}
return new BasicConnectionPool(url, user, password, pool);
}
// standard constructors
@Override
public Connection getConnection() {
Connection connection = connectionPool
.remove(connectionPool.size() - 1);
usedConnections.add(connection);
return connection;
}
@Override
public boolean releaseConnection(Connection connection) {
connectionPool.add(connection);
return usedConnections.remove(connection);
}
private static Connection createConnection(
String url, String user, String password)
throws SQLException {
return DriverManager.getConnection(url, user, password);
}
public int getSize() {
return connectionPool.size() + usedConnections.size();
}
// standard getters
}
然后按照最大線程池?cái)?shù)量進(jìn)行優(yōu)化
@Override
public Connection getConnection() throws SQLException {
if (connectionPool.isEmpty()) {
if (usedConnections.size() < MAX_POOL_SIZE) {
connectionPool.add(createConnection(url, user, password));
} else {
throw new RuntimeException(
"Maximum pool size reached, no available connections!");
}
}
Connection connection = connectionPool
.remove(connectionPool.size() - 1);
usedConnections.add(connection);
return connection;
}
新增一個正常關(guān)閉連接池的方法
public void shutdown() throws SQLException {
usedConnections.forEach(this::releaseConnection);
for (Connection c : connectionPool) {
c.close();
}
connectionPool.clear();
}
這個只是一個簡單連接池厌杜,并存在以下兩個問題
1忘嫉、并發(fā)獲取連接時鞭光,getConnection()會存在問題咳胃。尤其ArrayList還是線程非安全集合妆艘。
2彤灶、getConnection()發(fā)現(xiàn)連接池的連接到了最大數(shù)量,也直接報(bào)錯双仍。
然后參考一下這篇分析druid源碼邏輯進(jìn)一步了解連接邏輯
Druid-connection pool source code analysis
完整架構(gòu)圖枢希,重點(diǎn)分析DruidDataSrouce ,其中分析獲取和歸還連接的代碼