首页 > 解决方案 > Kotlin 中的对象池

问题描述

我想在 Kotlin 中使用对象池,并且更喜欢类似于apache commons pool的开源库。我不使用 apache commons pool 的唯一原因是它的借用方法是阻塞的。我想要一个具有以下功能的游泳池

  1. 设置 maxIdle 对象
  2. 清理闲置时间过长的对象
  3. 创建对象直到达到池容量(如果需要更多)
  4. 不允许用户泄露对象

我在互联网上搜索了一些想法,这个实现非常接近我想要的。我不使用的原因是它基于实验性 API。我也不高兴我需要启动一个无限循环来处理对象借用和回收,因为如果这个循环失败,整个池就死了。我更喜欢这些方法borrow(),并recycle()根据对对象的需求执行。

最后,我查看了在Ktor中实现的 ObjectPool,但我不明白借用和回收是如何实现的。有人可以解释一下这种方法pushTop()popTop()工作原理,或者只是给我指出关于这里应用这个概念的正确文献。如果我能弄清楚借用和回收方法是如何工作的,我想我可以采用这个。

那么我的要求是什么?

  1. 我怎样才能采用 Ktor 的DefaultObject池来实现我上面提到的目标

标签: kotlinkotlin-coroutines

解决方案


只是让 Commons Pool 提供暂停借用方法的想法。我没有花很多时间来推理这一点,所以我不能保证它完全有道理。但我的想法是,由于它已经尝试按照它们请求对象的顺序解除阻塞线程,所以让所有请求进入同一个线程并且协程将按照它们被请求的相同顺序接收它们的对象应该没问题。因此,您可以将单个线程调度程序附加到单个池。不利的一面是,即使池没有用尽,它最终也会短暂挂起以交换线程。

class SuspendingObjectPool<T>(private val sourcePool: ObjectPool<T>) : ObjectPool<T> by sourcePool {
    private val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
    
    suspend fun borrowObjectSuspending(): T = withContext(dispatcher) { borrowObject() }
}

fun <T> ObjectPool<T>.asSuspendingObjectPool() = SuspendingObjectPool(this)

推荐阅读