Java многопоточный контекст переключения против отправки новой задачи и решения для мониторинга очереди - PullRequest
0 голосов
/ 06 апреля 2020
  • О переключении контекста (синхронизации с ожиданием / уведомлением) между потоками и повторной отправке задачи (Callable / Runnable) в службу Executor, что лучше для производительности? как я знаю, для переключения контекста нужно сохранять / перезагружать данные потока, но если я повторно отправляю задачу в службу Executor, JVM необходимо перераспределить стек для переданной задачи, поэтому я думаю, что он имеет такую ​​же стоимость с контекстом переключения?

  • Я проектирую очередь задач для рабочих потоков, помещаю задачи в нее и поток мониторинга, чтобы принимать задачи в очереди, отправлять задачи в пул потоков (служба исполнителя). Но я думаю о том, когда работает поток монитора? Вариант 1. Использование потока «wait» для потока монитора, и рабочий поток уведомит поток монитора после того, как они поместят задачу в очередь. Вариант 2. Использование службы исполнителя планировщика для потока мониторинга для проверки очереди. -> Какой вариант лучше (по скорости, производительности) и с вариантом 2: как часто проверять очередь лучше?

большое спасибо за вашу помощь

1 Ответ

0 голосов
/ 06 апреля 2020
  1. Исполнитель обычно поддерживается пулом потоков. Так что стеки уже выделены. Кроме того, переключение контекста происходит только в том случае, если одно и то же ядро ​​ЦП должно выполнять оба потока. Современные процессоры имеют несколько ядер, поэтому переключение контекста не требуется.

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

  2. Нет необходимости иметь монитор поток, если сама очередь синхронизирована. Посмотрите, например, ArrayBlockingQueue; производители могут вызывать метод put() (который блокирует, когда в очереди нет свободного места), а потребители (потоки в пуле) вызывают take(), который блокирует, когда работа недоступна. Вот как реализовано ThreadPoolExecutor (точнее, на самом деле он вызывает offer(), поэтому по умолчанию не блокируется на стороне производителя).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...