NIO vs IO - довольно интересная тема для обсуждения.
По моему опыту, это два разных инструмента для двух разных работ. Я слышал о том, что IO называют подходом «поток на клиента», а NIO - подходом «один поток для всех клиентов», и я считаю, что имена, хотя и не на 100% точные, подходят достаточно.
Реальная проблема с NIO и IO, на мой взгляд, связана с масштабируемостью.
Сетевой уровень NIO будет (должен?) Использовать один поток для обработки селектора и отправки заданий на чтение / запись / принятие другим потокам. Это позволяет потоку, обрабатывающему селектор («поток селектора»), ничего не делать, кроме этого. Это позволяет гораздо быстрее реагировать при работе с большим количеством клиентов (обратите внимание на отсутствие фактических чисел). Теперь, когда NIO начинает разваливаться, это когда сервер получает так много чтения / записи / принятия, что поток селектора постоянно работает. Любые дополнительные задания после этого и сервер начинает лагать. Кроме того, поскольку все задания чтения / записи / принятия обрабатываются потоком селектора, добавление дополнительных процессоров к миксу не приведет к повышению производительности.
Сетевой уровень ввода-вывода, вероятно, будет использовать подход 1 поток на сокет, включая сокет прослушивания. Таким образом, количество потоков прямо пропорционально количеству клиентов. При умеренном количестве клиентов этот подход работает очень хорошо. Стоимость, которую платят с помощью этого подхода, выражается в виде стоимости потока. если у вас есть 2000 клиентов, подключенных к серверу ... у вас есть по крайней мере 2001 потоков. Даже в четырехъядерном процессоре, по 6 ядер на машину, у вас есть только 24 обрабатывающих узла (48, если считать HyperThreading) для обработки этих потоков 2001 года. Создание всех этих потоков стоит времени и оперативной памяти процессора, но даже если вы используете пул потоков, вам все равно придется платить за переключение контекста процессоров при их перемещении из потока в поток. Это может стать очень уродливым при высоких нагрузках на сервер и, если не будет правильно закодировано, может привести к остановке всей машины. С другой стороны, добавление процессоров к машине в этом случае улучшит производительность.
Теперь все хорошо, но в резюме, потому что в моем описании нет цифр, помогающих принять решение о переходе на IO или NIO. Это связано с тем, что нужно учитывать еще больше переменных:
- Время жизни клиента? Короткий или длинный?
- Объем данных, ожидаемых на одного клиента? Много маленьких кусков или несколько огромных кусков?
- Сколько клиентов предполагается подключить одновременно?
- В какой ОС вы работаете и какую JVM используете? Оба фактора в потоке и расходы на опрос.
Просто пища для размышлений. Чтобы ответить на вопрос, какой из них быстрее, NIO или IO: и то и другое:)