(Специфика этого вопроса касается мода для Minecraft. В общем, вопрос касается изменения размера пула потоков в зависимости от загрузки системы и доступности ЦП).
Я исхожу из фона Objective C и Apple libdispatch (Grand Central Dispatch) для планирования потоков.
Непосредственное беспокойство у меня вызывает попытка уменьшить размер пула потоков, когда запущена временная коллекция CMS. Рассматриваемая программа (Minecraft) хорошо работает только с коллекциями CMS. Гораздо менее актуальным, но все же «интересным» является уменьшение размера пула потоков, когда другие программы требуют значительных ресурсов ЦП (в частности, либо устройство записи экрана, либо поток twitch).
В Java я только что узнал о (глубокий вдох):
Executors, которые предоставляют доступ к пулам потоков (как фиксированного, так и регулируемого размера), с существованием кэшированных потоков (чтобы избежать накладных расходов, связанных с постоянным воссозданием новых потоков, или чтобы не беспокоиться о кодировании потоков для приостановки и возобновления в зависимости от рабочей нагрузки),
Executor (no s), который является универсальным интерфейсом для сообщения «Теперь пора выполнить this runnable ()»,
ExecutorService, который управляет пулами потоков в соответствии с Executor,
ThreadPoolExecutor, который фактически управляет пулом потоков, и имеет возможность сказать «Это максимальное количество потоков для использования».
При нормальной работе, примерно 5 раз в секунду, будет 50 операций с высоким приоритетом и 400 операций с низким приоритетом, отправляемых в пул потоков для каждого пользователя на сервере. Это для мощных машин.
Что я хочу сделать:
- Работайте с менее мощными машинами. Итак, если у компьютера всего 2 ядра, а основная программа (два основных потока плюс несколько второстепенных вспомогательных потоков) уже загружает ЦП на максимум, эти фоновые задачи будут конкурировать с основной программой и сборщиком мусора. В этом случае я не хочу уменьшать количество фоновых потоков (оно, вероятно, останется на уровне 2), но я хочу уменьшить объем запланированной работы. Итак, это просто «Как мне определить, когда рабочая нагрузка возрастает». Я подозреваю, что это всего лишь случай наблюдения за размером рабочей очереди, которую я использую, когда Executors.newCachedThreadPool ()
Но первая проблема: не могу найти ничего, чтобы вернуть размер очереди работ! ThreadPoolExecutor () может возвращать очередь, и я могу запросить это для размера, но newCachedThreadPool () возвращает только ExecutorService, который не позволяет мне запрашивать размер (или, скорее, я не знаю, как это сделать).
Если у меня «достаточно ядер», я хочу сказать пулу использовать больше потоков. В идеале достаточно, чтобы загрузка ЦП была близка к макс. Большинство задач, которые я хочу выполнить, связаны с процессором (дисковый ввод-вывод будет исключением, а не правилом; блокировка параллелизма также будет редкостью). Но я не хочу сильно перегружать потоки. Как определить «достаточное количество потоков», не перебирая доступные ядра?
Если, например, активируется запись экрана (или потоковая передача), загрузка ядра ЦП другими программами возрастет, и тогда я хочу уменьшить количество потоков; по мере того, как количество потоков уменьшается, а объем невыполненной работы очереди увеличивается, я могу уменьшить количество задач, которые я добавляю в очередь. Но я понятия не имею, как это обнаружить.