ThreadPoolExecutor - Могу ли я выбросить исключение, если пул заполнен - PullRequest
0 голосов
/ 18 февраля 2019

Можно ли генерировать исключение, если входящий запрос не может быть обработан?

Итак, у меня есть фиксированный пул потоков:

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

И я не хочу, чтобы запросы попадали в очередь потоков, если не могут быть обработаны, я просто хочу вызвать исключение.

Я пытаюсь проверить activeCount и выдать исключение, если оно больше максимального размера пула, но оно не работает так, как я хочу.

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

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Одним из решений для этого является использование очереди емкостью 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 (1-й и 2-й аргумент), который для вашего случая использования кажется подходящим.
  • MyQueue - это реализация BlockingQueue, которая принимает 0 в качестве емкости (т.е. которая может быть только пустой. Это, конечно,не очередь, но реализация этого позволяет беспрепятственно интегрироваться с ThreadPoolExecutor, предоставленным JDK.).

Дальнейшее рассмотрение :

При такой тонкой настройке вашего пула потоков, имейте в виду, что пропускная способность будет ограничена.Здесь, учитывая 4 потока и среднюю задержку L в секундах для задач, переданных в пул потоков, средняя пропускная способность, разрешенная этой конфигурацией, составляет 4/L задач / секунду.

0 голосов
/ 18 февраля 2019

Вы можете использовать политику насыщения, которая вступает в игру, когда ваша ограниченная очередь заполняется.Вы можете установить политику насыщения, вызвав setRejectedExecutionHandler() из ThreadPoolExecutor.Стандартные реализации: AbortPolicy, CallerRunsPolicy, DiscardPolicy и DiscardOldestPolicy.AbortPolicy является значением по умолчанию, которое выбрасывает RejectedExecutionException, когда ограниченная очередь заполняетсяВы также можете предоставить свою собственную реализацию.

...