Executors.newCachedThreadPool () по сравнению с Executors.newFixedThreadPool ()

Вы модифицируете исходный массив records в методе nameSearchFilter. Это неверно. Вам необходимо создать массив recordsToDisplay и использовать его для рисования строк таблицы и назначения результатов фильтрации в нем.

145
задан dimo414 25 July 2017 в 16:09
поделиться

2 ответа

Я думаю, что документация довольно хорошо объясняет разницу и использование этих двух функций:

newFixedThreadPool

Создает пул потоков, который повторно использует фиксированное количество отключенных потоков общая неограниченная очередь. В любом точки, не более nThreads потоков будут быть активными задачами обработки. Если дополнительные задачи отправляются, когда все потоки активны, они будут ждать в очереди, пока поток не будет доступный. Если какой-либо поток завершается из-за сбоя при исполнении до выключения новый примет его место, если необходимо выполнить последующие задачи. Темы в пул будет существовать, пока он не будет явно неисправность.

newCachedThreadPool

Создает пул потоков, который создает новые потоки по мере необходимости, но будут повторно использовать ранее созданные потоки, когда они доступны. Эти пулы будут обычно улучшают производительность программы, которые выполняют многие недолговечные асинхронные задачи. Призывы к исполнению будет повторно использовать ранее построенные темы, если есть. Если не существует поток доступен, новый поток будет быть создан и добавлен в пул. Потоки, которые не использовались для шестьдесят секунд прекращаются и удален из кеша. Таким образом, пул что остается без дела достаточно долго будет не потребляют никаких ресурсов. Обратите внимание, что бассейны с аналогичными свойствами, но разные детали (например, параметры тайм-аута) могут быть созданы с использованием конструкторов ThreadPoolExecutor.

Что касается ресурсов, newFixedThreadPool будет поддерживать работу всех потоков до тех пор, пока они не будут явно завершены. В newCachedThreadPool потоки, которые не использовались в течение шестидесяти секунд, завершаются и удаляются из кеша.

Учитывая это, потребление ресурсов будет во многом зависеть от ситуации. Например, если у вас огромное количество длительно выполняемых задач, я бы предложил FixedThreadPool . Что касается CachedThreadPool , в документации говорится, что «Эти пулы обычно улучшают производительность программ, которые выполняют множество краткосрочных асинхронных задач».

182
ответ дан 23 November 2019 в 22:49
поделиться

ThreadPoolExecutor класс является базовым внедрением для исполнителей, которые возвращаются из многих из эти Executors методы фабрики. Поэтому давайте приблизимся Зафиксированный и Кэшируемый пулы потоков от ThreadPoolExecutor перспектива.

ThreadPoolExecutor

основной конструктор из этого класса похож на это:

public ThreadPoolExecutor(
                  int corePoolSize,
                  int maximumPoolSize,
                  long keepAliveTime,
                  TimeUnit unit,
                  BlockingQueue<Runnable> workQueue,
                  ThreadFactory threadFactory,
                  RejectedExecutionHandler handler
)

Базовый Размер Пула

Эти corePoolSize определяет минимальный размер целевого пула потоков. реализация поддержала бы пул того размера, даже при отсутствии задач выполниться.

Максимальный Размер Пула

Эти maximumPoolSize является максимальным количеством потоков, которые могут быть активными сразу.

После того, как пул потоков растет и становится больше, чем corePoolSize порог, исполнитель может завершить неактивные потоки и достигнуть к corePoolSize снова. Если allowCoreThreadTimeOut верно, то исполнитель может даже завершить базовые потоки пула, если они были неактивны больше чем [1 112] порог.

, Таким образом, нижняя строка - то, если потоки остаются неактивными больше чем [1 113] порог, они могут быть завершены, так как нет никакого спроса на них.

Организация очередей

, Что происходит, когда новая задача входит и все базовые потоки занята? новые задачи будут поставлены в очередь в том BlockingQueue<Runnable> экземпляр. Когда поток становится свободным, одна из тех задач с очередями может быть обработана.

существуют различные реализации эти BlockingQueue интерфейс в Java, таким образом, мы можем реализовать различные подходы организации очередей как:

  1. Ограниченная Очередь : Новые задачи были бы поставлены в очередь в ограниченной очереди задачи.

  2. Неограниченная Очередь : Новые задачи были бы поставлены в очередь в неограниченной очереди задачи. Таким образом, эта очередь может вырасти так, как размер "кучи" позволяет.

  3. Синхронная Передача : Мы можем также использовать SynchronousQueue для организации очередей новых задач. В этом случае, при организации очередей новой задачи, другой поток должен уже ожидать той задачи.

Представление Работы

Вот состоит в том, как эти ThreadPoolExecutor выполняет новую задачу:

  1. , Если меньше чем [1 118] потоки работают, попытки начать новую дискуссию с данной задачей как ее первое задание.
  2. Иначе, это пытается ставить в очередь новую задачу с помощью BlockingQueue#offer метод. offer метод не заблокируется, если очередь будет полна и сразу возвратится false.
  3. , Если этому не удается поставить новую задачу в очередь (т.е. offer возвраты false), затем это пытается добавить новый поток к пулу потоков с этой задачей как ее первое задание.
  4. , Если этому не удается добавить новый поток, затем исполнитель или закрывается или насыщается. Так или иначе новая задача была бы отклонена с помощью обеспеченного RejectedExecutionHandler.

основное различие между фиксированными и кэшируемыми пулами потоков сводится к этим трем факторам:

  1. Базовый Размер Пула
  2. Максимальный Размер Пула
  3. Организация очередей

+-----------+-----------+-------------------+---------------------------------+
| Pool Type | Core Size |    Maximum Size   |         Queuing Strategy        |
+-----------+-----------+-------------------+---------------------------------+
|   Fixed   | n (fixed) |     n (fixed)     | Unbounded `LinkedBlockingQueue` |
+-----------+-----------+-------------------+---------------------------------+
|   Cached  |     0     | Integer.MAX_VALUE |        `SynchronousQueue`       |
+-----------+-----------+-------------------+---------------------------------+

<час>

Фиксированный Пул потоков

<час> Здесь то, как Excutors.newFixedThreadPool(n) работы:
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

, Как Вы видите:

  • размер пула потоков фиксируется.
  • , Если существует высокий спрос, это не вырастет.
  • , Если потоки неактивны в течение достаточно долгого времени, это не уменьшится.
  • предположим все те потоки заняты некоторыми продолжительными задачами, и частота поступления все еще довольно высока. Так как исполнитель использует неограниченную очередь, она может использовать огромную часть "кучи". Будучи достаточно неудачными, мы можем испытать OutOfMemoryError.

, Когда я должен использовать один или другой? Какая стратегия лучше с точки зрения использования ресурса?

пул потоков фиксированного размера А, кажется, хороший кандидат, когда мы собираемся ограничить количество параллельных задач в целях управления ресурсами .

, Например, если мы собираемся использовать исполнителя для обрабатывания запросов веб-сервера, фиксированный исполнитель может обработать пакеты запроса более обоснованно.

Для еще лучшего управления ресурсами, это настоятельно рекомендовано для создания пользовательского ThreadPoolExecutor с ограниченным BlockingQueue<T> реализация вместе с разумным RejectedExecutionHandler.

<час>

Кэшируемый Пул потоков

<час>

Вот то, как Executors.newCachedThreadPool() работы:

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

, Как Вы видите:

  • пул потоков может вырасти от нулевых потоков до [1 131]. Практически, пул потоков неограничен.
  • , Если поток неактивен больше 1 минуты, он может быть завершен. Таким образом, пул может уменьшиться, если потоки остаются слишком много неактивными.
  • , Если все выделенные потоки заняты, в то время как новая задача входит, затем она создает новый поток как предложение новой задачи к SynchronousQueue всегда сбои, когда нет никого на другом конце для принятия его!

, Когда я должен использовать один или другой? Какая стратегия лучше с точки зрения использования ресурса?

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

0
ответ дан 23 November 2019 в 22:49
поделиться