Каковы различия в реализации Schedulers.computation и Schedulers.io?

Почему они используются для разных задач? Что отличает их при обработке вычислительной задачи против задачи io?

Schedulers.computation () - предназначен для вычислительной работы, такой как циклы обработки событий и обработка обратных вызовов; не используйте этот планировщик для ввода / вывода (используйте Schedulers.io() вместо этого); количество потоков по умолчанию равно количеству процессоров


Schedulers.io() - предназначен для работы, связанной с вводом / выводом, такой как асинхронная производительность блокирования ввода / вывода, этот планировщик опирается на пул потоков, который будет расти по мере необходимости; для обычной вычислительной работы переключитесь на Schedulers.computation(); По умолчанию Schedulers.io() - это CachedThreadScheduler, который похож на новый планировщик потоков с кэшированием потоков.

2 ответа

Решение

Ввод / вывод и вычисления - это очень разные рабочие нагрузки.

Вычисления связаны исключительно с ЦП, поэтому вы хотите ограничить количество потоков, чтобы они не боролись за ЦП и не морили себя голодом. Если у вас есть 1000 потоков, которые пытаются работать на 8 ядрах, вы, вероятно, будете в плохом состоянии. Schedulers.computation () ограничен количеством ядер.

Ввод-вывод отличается, поскольку, хотя им обычно требуется поток для поддержки контекста, они на самом деле не используют ЦП - они просто спят, пока не завершится ввод-вывод. Совершенно нормально иметь 1000 операций ввода-вывода на одноядерном компьютере, поскольку они все спят большую часть времени. Schedulers.io () не ограничен и порождает столько потоков, сколько необходимо

Наиболее важным моментом является то, что и Schedulers.io, и Schedulers.computation поддерживаются неограниченными пулами потоков с автоматическим восстановлением. Эта характеристика является общей для Schedulers.from(Executor) только в том случае, если Исполнитель создан с помощью newCachedThreadPool (без ограничений с пулом потоков с автоматическим возвратом).

Schedulers.computation по умолчанию настроен с количеством потоков, равным количеству доступных процессоров, поэтому вычисления выполняются настолько быстро, насколько это возможно. Вы можете увеличить это число, но это может привести к накладным расходам на переключение потоков и замедлить вычисления.

Что касается Schedulers.io, вы должны использовать его только для блокировки операций ввода-вывода, поскольку они будут блокировать вызывающий поток. Не используйте его, если ваш вызов ввода-вывода осуществляется через асинхронный или реактивный API, поскольку в Scheduler.io отсутствует механизм для обратного вызова.

При этом важная роль этих планировщиков заключается в предоставлении многопоточного контекста оператору flatMap(), обеспечивающем параллелизм в ядре реактивного потока.

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

Надеюсь это поможет,

Softjake

Другие вопросы по тегам