我有一个Runnable,它从连接池中获取连接,如下所示,并有60秒的时间对连接做一些事情:
private static ConnectionPoolDataSource cpds; // MysqlConnectionPoolDataSource
public void run(){
while((System.currentTimeMillis()-created)<60000){
try(Connection conn = cpds.getPooledConnection().getConnection()){
//do something
}catch(SQLException sqle){}
}
}
当线程在60秒后死亡时,我假设连接返回到池中,当创建新线程时,连接可以重用。但是当我列出我的网络连接时,随着更多的线程被创建,列表不断增长。如上所述创建的连接是否正确返回到池中,如果是,我如何强制连接重新使用?
2条答案
按热度按时间webghufk1#
您实际上并没有使用连接池。
ConnectionPoolDataSource
不打算直接使用。它的目的是作为PooledConnection
对象的(特殊)DataSource
,然后由提供连接池的(普通)DataSource
实现保存在连接池中。普通开发人员不应该直接使用
ConnectionPoolDataSource
,它旨在与应用服务器提供的连接池一起使用,或者 Package 到提供连接池的通用DataSource
中。当从连接池请求
Connection
时,它将检出现有的PooledConnection
(或从其ConnectionPoolDataSource
请求新的PooledConnection
),检索Connection
并将其返回给用户。当用户关闭Connection
时,PooledConnection
将向连接池发出信号,表示它再次可用。在本例中,您正在创建一个
PooledConnection
,从中检索一个Connection
,然后丢弃PooledConnection
。这意味着PooledConnection
被放弃,并且它与数据库的物理连接不能被重用,并且在最终被垃圾收集时将被关闭/丢弃(通常,当连接池想要关闭物理连接时,它将在PooledConnection
上调用close()
)。您需要使用Application Server提供的连接池,或者使用通用连接池,如DBCP、c3 p0或HikariCP。
nimxete22#
您没有说明连接池使用的是什么,因此答案是“可能”。
但是,大多数池都有一些方法来检测已放弃的连接。例如,DBCP提供了
removeAbandoned
和removeAbandonedTimeout
配置参数。这些不会立即将连接返回到池中,因此您仍然会看到连接数量在增长,直到超时过期(并且希望,由于您处于紧密循环中,因此您已经设置了打开连接数量的最大值)。