HikariPool 的 getConnection()方法
在上一篇《HikariCP 获取连接流程源码分析一》中,我们分析了 HikariDataSource 的getConnection()方法,而这个方法,其实详细的实现细节都是在 HikariPool 的 getConnection()方法中,我们来分析下 HikariPool 的 getConnection()方法。
代码如下:
public final Connection getConnection() throws SQLException {
return getConnection(connectionTimeout);
}
这里又调用了一个有参的 getConnection()方法,但是我们并没有传参数 connectionTimeout,这个是哪里来的呢?这个其实就是用户在初始化连接池的时候设置的参数connectionTimeout,它表示获取连接的超时时间,不配置的话默认值 30 秒。我们继续看下getConnection(connectionTimeout);的实现:
public final Connection getConnection(final long hardTimeout) throws SQLException {
//①
//获取连接的时候申请令牌, 主要是为了连接池挂起的时候, 控制用户不能获取连接
//当连接池挂起的时候, Semaphore的 10000 个令牌都会被占用, 此处就会一直阻塞线程等待令牌
suspendResumeLock.acquire();
//记录获取连接的开始时间, 用于超时判断
final long startTime = clockSource.currentTime();
try {
long timeout = hardTimeout;
do {
//②
//从连接池获取连接, 超时时间timeout
final PoolEntry poolEntry = connectionBag.borrow(timeout, MILLISECONDS);
//borrow方法在超时的时候才会返回 null
if (poolEntry == null) {
break; // We timed out... break and throw exception
}
final long now = clockSource.currentTime();
//③
//获取连接的时候, 判断连接是否已经被标记移除
if (poolEntry.isMarkedEvicted() || (clockSource.elapsedMillis(poolEntry.lastAccessed, now) > ALIVE_BYPASS_WINDOW_MS && !isConnectionAlive(poolEntry.connection))) {
//如果连接超出max