druid 源码阅读(十一)maxWait 参数
作者:爱晒太阳的大白
- 2022 年 5 月 20 日
本文字数:2055 字
阅读完需:约 7 分钟
1、含义
获取连接时最大等待时间,单位毫秒。配置了 maxWait 之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置 useUnfairLock 属性为 true 使用非公平锁。
2、源码
可以通过 DruidDataSource.setMaxWait(maxWaitMills)开启该参数,查看这个方法的代码:
public void setMaxWait(long maxWaitMillis) {
if (maxWaitMillis == this.maxWait) {
return;
}
if (maxWaitMillis > 0 && useUnfairLock == null && !this.inited) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
if ((!this.inited) && (!lock.isFair())) {
this.lock = new ReentrantLock(true);
this.notEmpty = this.lock.newCondition();
this.empty = this.lock.newCondition();
}
} finally {
lock.unlock();
}
}
if (inited) {
LOG.error("maxWait changed : " + this.maxWait + " -> " + maxWaitMillis);
}
this.maxWait = maxWaitMillis;
}
复制代码
设置 maxWait 后,但是没有设置 useUnfairLock 的话会直接将 dataSource 的锁模式设置为公平锁。如果设置 useUnfairLock 的话会不再设置公平锁,否则就使用先初始化的锁模式,但是如果想使用 maxWait 并且使用非公平锁模式,必须要先设置 useUnfairLock,再设置 maxWait,否则 useUnfiarLock 会不起作用。
继续看看都有哪些地方使用了 maxWait 这个参数,只有在 getConnectionInternal(long maxWaitMillis)这个方法中,这个方法中主要在如下代码中使用
if (maxWait > 0) {
holder = pollLast(nanos);
} else {
holder = takeLast();
}
复制代码
查看 pollLast 方法,
private DruidConnectionHolder pollLast(long nanos) throws InterruptedException, SQLException {
long estimate = nanos;
for (;;) {
if (poolingCount == 0) {
//使用信号量开始创建连接
emptySignal(); // send signal to CreateThread create connection
if (failFast && isFailContinuous()) {
throw new DataSourceNotAvailableException(createError);
}
if (estimate <= 0) {
waitNanosLocal.set(nanos - estimate);
return null;
}
notEmptyWaitThreadCount++;
if (notEmptyWaitThreadCount > notEmptyWaitThreadPeak) {
notEmptyWaitThreadPeak = notEmptyWaitThreadCount;
}
try {
//等待连接被创建
long startEstimate = estimate;
//返回剩余等待时间,如果为负数,说明超时了
estimate = notEmpty.awaitNanos(estimate); // signal by
// recycle or
// creator
notEmptyWaitCount++;
notEmptyWaitNanos += (startEstimate - estimate);
if (!enable) {
connectErrorCountUpdater.incrementAndGet(this);
if (disableException != null) {
throw disableException;
}
throw new DataSourceDisableException();
}
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
notEmptySignalCount++;
throw ie;
} finally {
notEmptyWaitThreadCount--;
}
if (poolingCount == 0) {
if (estimate > 0) {
continue;
}
waitNanosLocal.set(nanos - estimate);
return null;
}
}
decrementPoolingCount();
DruidConnectionHolder last = connections[poolingCount];
connections[poolingCount] = null;
long waitNanos = nanos - estimate;
//等待了多久
last.setLastNotEmptyWaitNanos(waitNanos);
return last;
}
}
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 2
爱晒太阳的大白
关注
还未添加个人签名 2021.05.30 加入
还未添加个人简介
评论