写点什么

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; } }
复制代码


用户头像

还未添加个人签名 2021.05.30 加入

还未添加个人简介

评论

发布
暂无评论
druid 源码阅读(十一)maxWait 参数_5月月更_爱晒太阳的大白_InfoQ写作社区