Лучший подход: древовидная структура против исполнителя пула потоков

1

Ребята, я немного расстроен между Tree Set и Thread Pool Executor

Ниже приведен сценарий:

Первый подход

  1. Я должен использовать структуру, в которой есть задачи в ней с приоритетами каждой задачи. Теперь на treeset constructor (с интерфейсом comparator)
  2. Я могу сравнить задачу с приоритетами, и на основании этого задачи упорядочены должным образом.
  3. Теперь после этого задачи должны обрабатываться в порядке приоритета с помощью итерации набора деревьев и выполнять каждую задачу поочередно.

Второй подход

  1. второй подход заключается в том, чтобы сделать какое-то логическое построение и использовать основные функциональные возможности Thread pool executor и для этого я воодушевился этой ссылкой, и я достиг своих требований с этим подходом, который сначала выберет приоритетное задание и выполнит его сначала, и таким же образом он выполнит все задачи.

Теперь моя путаница заключается в том, какой из них лучше всего использовать с точки зрения затрат на производительность, гибкости (увеличение/уменьшение потоков) и т.д. И почему я должен ее выбирать?

Любые предложения и ответы высоко ценятся.

  • 1
    Я не думаю, что приоритет пула потоков гарантированно заставит эти потоки идти первыми, поэтому ваш набор деревьев звучит лучше.
  • 2
    Большинство примеров с исполнителями, которые я видел, используют очереди. Почему бы не использовать PriorityQueue с тем же компаратором? Спрашивать, что является «лучшим», действительно зависит от вашего варианта использования и рабочей нагрузки, поскольку нет единого ответа, который всегда будет работать для вашей конкретной задачи.
Показать ещё 14 комментариев
Теги:
multithreading
collections
priority-queue
threadpoolexecutor

3 ответа

0
Лучший ответ

Наконец, получился настоящий победитель из этих двух. Я должен выбрать для Thread pool Executor из-за следующих причин

  1. Производительность: здесь, если мы видим, использование максимального ресурса является основным мотивом для получения производительности при большой нагрузке. Поэтому, если мы будем использовать потоки в это время, это будет обеспечивать высокую производительность как преимущество многопоточности.
  2. Гибкость: гибкость с точки зрения масштабируемого использования ресурсов, т.е. В течение низкого времени мы можем сократить количество рабочих потоков в архитектуре thread pool executor и наоборот.
  3. Меньшее количество итераций и минимальных обновлений: если мы каждый раз поддерживаем набор деревьев, он будет проверяться с помощью интерфейса comparator хотя он имеет сложность O (logn), но после этого мы должны его получить, и он станет последовательным потоком одиночных поэтому мы не будем использовать многопоточную среду.
  4. Более быстрая обработка: с помощью архитектуры потоковой обработки мы можем добиться более высокой производительности.

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

0

Вы можете попробовать DelayedQueue в обычном threadpool.

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(size, size, 0, TimeUnit.DAYS, new DelayQueue<>());
threadPoolExecutor.execute(runnable);

Runnable должен реализовывать Comparable. Поэтому в этой реализации приоритет будет зависеть от задержки.

Такой подход будет проще реализовать.

0

В вашем вопросе есть два разных понятия приоритета:

  • стартовый приоритет: в каком порядке задачи отправляются на исполнение (пункт 1 вашего первого подхода)

  • приоритет выполнения: в каком порядке рассматриваются потоки заказов для планирования (точка 3)

Эти два свойства оказываются одинаковыми в вашем сценарии, поэтому набор деревьев поможет вам определить их оба. Исполнитель поможет вам обеспечить их соблюдение, но вам понадобится специальный пользовательский исполнитель (на основе пула потоков или нет), чтобы начать ваши потоки с определенным приоритетом. В принципе, каждый раз, когда задача вытягивается из очереди приоритетов, она должна быть связана с потоком, установленным на уровне приоритета задачи. Я предполагаю, что это функция, которую реализует реализация исполнителя в статье, которую вы указываете, и, следовательно, что вы делаете.

Что касается пулов потоков, из документации:

Использование рабочих потоков минимизирует накладные расходы из-за создания потоков. Объекты Thread используют значительный объем памяти, а в крупномасштабном приложении выделение и освобождение многих объектов потоков создает значительные накладные расходы на управление памятью.

Рабочие потоки - это потоки, управляемые файловыми путями, и консервативно перерабатываются (в отличие от уничтоженных и воссозданных) для обработки последовательностей задач. Я не думаю, что это имеет большое значение в отношении приоритетной обработки, но это оптимизирует использование вами ресурсов.

Что касается реализации из статьи, в коде используется простой блокирующий деб для обработки входящих задач, следовательно, это простая схема приоритета fifo. Он не изменяет порядок задач.

  • 1
    Точно, функция (приоритет потока такой же, как у задачи) реализована во втором подходе. Подход с использованием tree set - это хорошо, но моя путаница связана с трудоемкостью, затратами на производительность при большой нагрузке, гибкостью и т. д. в зависимости от того, какой из них выбрать.
  • 0
    Ах, прости, я упустил этот момент. Я предполагаю, что без конкретных деталей реализации будет сложно оценить их с точки зрения сложности и стоимости.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню