Чего я не понимаю: нам нужен поток / обработчик, чтобы ждать этих данных, верно?
Не совсем. Идея NIO заключается в том, что никакие потоки никогда не блокируются.
Это интересно, потому что операционная система уже работает в неблокирующем режиме. Это наши языки программирования, которые были смоделированы блокирующим образом.
В качестве примера представьте, что у вас есть компьютер с одним процессором. Любая операция ввода-вывода, которую вы выполняете, будет на порядки медленнее, чем процессор, не так ли? Скажем, вы хотите прочитать файл. Как вы думаете, будет ли ЦП оставаться там, бездействовать, ничего не делать, пока головка диска берет несколько байтов и помещает их в дисковый буфер? Очевидно нет. Операционная система зарегистрирует прерывание (то есть обратный вызов) и тем временем будет использовать ценный ЦП для чего-то еще. Когда головке диска удалось прочитать несколько байтов и сделать их доступными для использования, произойдет прерывание, и ОС обратит на это внимание, восстановит предыдущий блок процесса и выделит некоторое время ЦП для обработки доступных данных.
Итак, в этом случае ЦП подобен потоку в вашем приложении. Это никогда не блокируется. Он всегда делает какие-то вещи, связанные с процессором.
Идея программирования NIO такая же. В случае, если вы разоблачаете, представьте, что ваш HTTP-сервер имеет единственный поток. Когда вы получаете запрос от своего клиента, вам необходимо сделать восходящий запрос (который представляет собой ввод-вывод). Итак, что здесь будет делать структура NIO, так это выдать запрос и зарегистрировать обратный вызов, когда ответ будет доступен.
Сразу после этого ваш ценный единственный поток освобождается для обслуживания еще одного запроса, который регистрирует другой обратный вызов, и так далее, и так далее.
Когда обратный вызов разрешится, он будет автоматически запланирован для обработки вашим единственным потоком.
Таким образом, этот поток работает как цикл событий, в котором вы должны планировать только то, что связано с процессором. Каждый раз, когда вам нужно выполнить ввод-вывод, это делается неблокирующим образом, и когда этот ввод-вывод завершен, некоторый обратный вызов, связанный с процессором, помещается в цикл событий для обработки ответа.
Это мощная концепция, потому что с очень небольшим количеством потоков вы можете обрабатывать тысячи запросов и, следовательно, вы можете легче масштабироваться. Делайте больше с меньшими затратами.
Эта функция является одним из основных аргументов в пользу Node.js и является причиной того, что даже при использовании одного потока он может использоваться для разработки серверных приложений.
Точно так же это причина распространения таких фреймворков, как Netty, RxJava, Reactive Streams Initiative и Project Reactor. Все они стремятся продвигать этот тип оптимизации и модели программирования.
Существует также интересное движение новых фреймворков, которые используют эти мощные функции и пытаются конкурировать или дополнять друг друга. Я говорю об интересных проектах, таких как Vert.x и Ratpack. И я почти уверен, что для других языков существует гораздо больше.
person
Edwin Dalorzo
schedule
05.04.2018
select
,poll
и аналогичные механизмы позволяют дождаться, пока любой из нескольких сокетов станет доступным для чтения или записи. - person Gil Hamilton   schedule 05.04.2018