ThreadPoolExecutor - 如果池已满,我可以抛出异常

问题描述 投票:2回答:2

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

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

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

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

我试图检查activeCount并抛出异常,如果大于最大池大小但它不能正常工作。

private fun checkPoolSize() {
    if (executor.activeCount >= 4) {
        throw RuntimeException("Request can't be handled. ")
    }
}
multithreading kotlin concurrency java.util.concurrent threadpoolexecutor
2个回答
2
投票

对此的一个解决方案是使用容量为0的队列和java.util.concurrent.ThreadPoolExecutor.AbortPolicy作为RejectedExecutionHandler

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

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(第一和第二个参数),对于您的用例似乎是合适的。
  • MyQueueBlockingQueue的一个实现,它接受0作为容量(即只能是空的。这当然不是队列,但实现这个允许与JDK提供的ThreadPoolExecutor无缝集成。)。

进一步考虑:

通过对线程池的这种微调,请注意吞吐量将受到限制。这里,考虑到提交给线程池的任务的4个线程和平均等待时间L(以秒为单位),此配置允许的平均吞吐量为4/L tasks / second。


2
投票

当有界队列填满时,您可以使用饱和策略。您可以通过调用setRejectedExecutionHandler()ThreadPoolExecutor来设置饱和度策略。开箱即用的实现是AbortPolicyCallerRunsPolicyDiscardPolicyDiscardOldestPolicyAbortPolicy是默认值,当有界队列填满时会抛出RejectedExecutionException。您还可以提供自己的自定义实现。

© www.soinside.com 2019 - 2024. All rights reserved.