首页 > 解决方案 > ThreadPoolExecutor - 如果池已满,我可以抛出异常吗

问题描述

如果无法处理传入的请求,是否可以抛出异常?

所以,我有一些固定的线程池:

private val executor: ThreadPoolExecutor = Executors.newFixedThreadPool(4) as ThreadPoolExecutor

如果无法处理,我不希望请求进入线程队列,我只想抛出异常。

我正在尝试检查 activeCount 并在大于最大池大小时抛出异常,但它不像我想要的那样工作。

private fun checkPoolSize() {
    if (executor.activeCount >= 4) {
        throw RuntimeException("Request can't be handled. ")
    }
}

标签: multithreadingkotlinconcurrencyjava.util.concurrentthreadpoolexecutor

解决方案


一种解决方案是使用容量为 0 的队列并java.util.concurrent.ThreadPoolExecutor.AbortPolicy作为RejectedExecutionHandler.

中的静态方法Executors不会公开您想要的完整参数集,因此您需要ThreadPoolExecutor直接实例化 a。在您的情况下,您可以使用以下内容:

new ThreadPoolExecutor(4,                                     /* Core pool size                    */
                       4,                                     /* Max pool size                     */
                       0, TimeUnit.SECONDS,                   /* Core th. keep-alive               */
                       new MyQueue<Runnable>(0),              /* No queueing allowed               */
                       Executors.defaultThreadFactory(),      /* default                           */
                       new AbortPolicy())                     /* throws when all core threads busy */

几点注意事项:

  • 0 秒(第 3 和第 4 个参数)对应于核心线程保持活动时间。设置为 0 意味着您的核心线程即使处于空闲状态也永远不会停止。这是使用时的默认行为Executors.newFixedThreadPool(4)
  • Executors.defaultThreadFactory()是默认线程工厂,与使用Executors.newFixedThreadPool(4).
  • 这里核心和最大线程池大小设置为 4(第一个和第二个参数),这对于您的用例来说似乎是合适的。
  • MyQueue是一个BlockingQueue接受 0 作为容量的实现(即只能为空。这当然不是队列,但实现它可以与ThreadPoolExecutorJDK 提供的无缝集成。)。

进一步考虑

通过对线程池进行如此微调,请注意吞吐量将受到限制。在这里,考虑到 4 个线程和提交到线程池的任务的平均延迟L(以秒为单位),此配置允许的平均吞吐量为4/L任务/秒。


推荐阅读