You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用GenericObjectPool的borrowObject避免线程无限阻塞?

Apache Commons Pool2 2.8.1 对象池借取对象时的线程阻塞问题

配置对象池大小为1,启动3个线程借取对象时出现线程无限阻塞,应用直接挂起直至进程终止,具体执行流程如下:

    1. 第一个线程进入borrowObject方法,因为没有空闲对象可通过pollFirst获取,所以创建新对象继续执行:
p = (PooledObject)this.idleObjects.pollFirst();
if (p == null) {
  p = this.create();
  if (p != null) {
     create = true;
  }
}
    1. 另外两个线程执行相同逻辑,检测到无空闲对象后尝试创建新对象,但由于池大小限制为1,无法创建新对象,转而进入idleObjects.takeFirst()等待。此时blockWhenExhausted设为true,borrowMaxWaitMillis设为-1(无超时等待):
if (blockWhenExhausted) {
   if (p == null) {
      if (borrowMaxWaitMillis < 0L) {
           p = (PooledObject)this.idleObjects.takeFirst();
      } else {
           p = (PooledObject)this.idleObjects.pollFirst(borrowMaxWaitMillis, TimeUnit.MILLISECONDS);
      }
   }

   if (p == null) {
      throw new NoSuchElementException("Timeout waiting for idle object");
   }
}
    1. 第一个线程执行this.factory.activateObject(p)激活对象后,调用this.factory.validateObject(p)验证对象,验证返回false(比如连接已断开),因此触发this.destroy(p)销毁该对象:
private void destroy(PooledObject<T> toDestroy) throws Exception {
     toDestroy.invalidate();
     this.idleObjects.remove(toDestroy);
     this.allObjects.remove(new BaseGenericObjectPool.IdentityWrapper(toDestroy.getObject()));

     try {
        this.factory.destroyObject(toDestroy);
     } finally {
        this.destroyedCount.incrementAndGet();
        this.createCount.decrementAndGet();
     }
}
    1. 对象被销毁后从idleObjects和allObjects列表中移除,但另外两个线程仍在takeFirst()方法中等待从idleObjects取对象,导致无限期阻塞:
public E takeFirst() throws InterruptedException {
   this.lock.lock();

   Object var2;
   try {
      Object x;
      while((x = this.unlinkFirst()) == null) {
         this.notEmpty.await();
      }

      var2 = x;
    } finally {
      this.lock.unlock();
    }
    return var2;
}

问题核心

destroy方法销毁对象并从idleObjects移除后,未唤醒等待在notEmpty条件队列上的线程。这些线程会一直卡在this.notEmpty.await()处,永远无法被唤醒,最终导致应用挂起。

内容的提问来源于stack exchange,提问作者Sart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:15:34