ThreadPoolExecutor - 如果池已满,我可以抛出异常吗
ThreadPoolExecutor - Can I throw exception if pool is full
如果无法处理传入的请求,是否可以抛出异常?
所以,我有一些固定的线程池:
private val executor: ThreadPoolExecutor = Executors.newFixedThreadPool(4) as ThreadPoolExecutor
如果无法处理,我不希望请求进入线程队列,我只想抛出异常。
我正在尝试检查 activeCount 并在大于最大池大小时抛出异常,但它没有像我想要的那样工作。
private fun checkPoolSize() {
if (executor.activeCount >= 4) {
throw RuntimeException("Request can't be handled. ")
}
}
您可以使用饱和策略,它会在您的有界队列填满时发挥作用。您可以通过调用 ThreadPoolExecutor
的 setRejectedExecutionHandler()
来设置饱和策略。开箱即用的实现是 AbortPolicy
、CallerRunsPolicy
、DiscardPolicy
和 DiscardOldestPolicy
。 AbortPolicy
是默认值,当有界队列填满时抛出 RejectedExecutionException
。您还可以提供自己的自定义实现。
一个解决方案是使用容量为 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(第一个和第二个参数),这对于您的用例来说似乎是合适的。
MyQueue
是 BlockingQueue
的一个实现,它接受 0 作为容量(即只能为空。这当然不是队列,但实现它允许与 ThreadPoolExecutor
由JDK提供。)。
进一步考虑:
通过对线程池进行如此微调,请注意吞吐量将受到限制。在这里,考虑到提交到线程池的任务有 4 个线程和平均延迟 L
秒,此配置允许的平均吞吐量为 4/L
tasks/second.
如果无法处理传入的请求,是否可以抛出异常?
所以,我有一些固定的线程池:
private val executor: ThreadPoolExecutor = Executors.newFixedThreadPool(4) as ThreadPoolExecutor
如果无法处理,我不希望请求进入线程队列,我只想抛出异常。
我正在尝试检查 activeCount 并在大于最大池大小时抛出异常,但它没有像我想要的那样工作。
private fun checkPoolSize() {
if (executor.activeCount >= 4) {
throw RuntimeException("Request can't be handled. ")
}
}
您可以使用饱和策略,它会在您的有界队列填满时发挥作用。您可以通过调用 ThreadPoolExecutor
的 setRejectedExecutionHandler()
来设置饱和策略。开箱即用的实现是 AbortPolicy
、CallerRunsPolicy
、DiscardPolicy
和 DiscardOldestPolicy
。 AbortPolicy
是默认值,当有界队列填满时抛出 RejectedExecutionException
。您还可以提供自己的自定义实现。
一个解决方案是使用容量为 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(第一个和第二个参数),这对于您的用例来说似乎是合适的。
MyQueue
是BlockingQueue
的一个实现,它接受 0 作为容量(即只能为空。这当然不是队列,但实现它允许与ThreadPoolExecutor
由JDK提供。)。
进一步考虑:
通过对线程池进行如此微调,请注意吞吐量将受到限制。在这里,考虑到提交到线程池的任务有 4 个线程和平均延迟 L
秒,此配置允许的平均吞吐量为 4/L
tasks/second.