Java неблокирующий и асинхронный ввод-вывод с NIO & NIO.2 (JSR203) - реализации реактора/Proactor

Итак, здесь я читаю одну из моих любимых книг шаблонов программного обеспечения (архитектура программного обеспечения, ориентированная на шаблоны для параллельных и сетевых объектов), в частности разделы о шаблонах асинхронного ввода-вывода Proactor/Reactor. Я вижу, как с помощью выбираемых каналов я могу реализовать асинхронный механизм ввода-вывода в стиле реактора довольно легко (и сделал это). Но я не вижу, как я бы реализовал правильный механизм Proactor с неблокирующими записями. Это использование OS управляемые неблокирующие функции записи.

функциональность, поддерживаемая конкретными вызовами ОС, такими как GetQueuedCompletionStatus под win32.

Я видел, что Java 7 приносит некоторые обновления NIO с асинхронными обработчиками завершения (которые, кажется, находятся в правильном направлении). Как говорится... Учитывая отсутствие единой кросс-платформенной поддержки асинхронных операций, управляемых ОС (в частности, асинхронной записи), я предполагаю, что это quassy-реализация, которая не использовать встроенную поддержку ОС.

Итак, мои вопросы, это proactor на основе ИО обращение возможно в Java таким образом, что его выгодно использовать в определенных случаях; и, если Java НИО поддерживает proactor на основе ввода-вывода обращения (либо на Java 6 или Java 7) - это операционная система управляемого асинхронного ввода-вывода (т. е. завершение вызовов от ОС) используются? Кроме того, если реализация чисто в-VM, преимущества производительности настолько малы, что использование проактивной обработки событий предлагает не что иное, как другой (возможно, более простой) способ построения параллельного программного обеспечения для обработки сети.

для всех, кто заинтересован в проактивной обработке событий вот хорошая статья это описывает плюсы / минусы и сравнение как с традиционными потоками на соединение, так и с реактивными моделями ввода-вывода.

4 ответов


есть много факторов, участвующих в этом. Я постараюсь обобщить свои выводы как можно лучше (учитывая тот факт, что есть разногласия относительно полезности реализаций обработки реактора и проактора IO).

Это proactor на основе ИО регулировать можно в Java таким образом, что это выгодно использовать для специфического вариант развития событий.

Java 1.4 ввел неблокирующий IO, который не совпадает с асинхронным IO. Java SE 7 вводит асинхронный ввод-вывод с JSR203, делая возможными реализации обработки ввода-вывода в стиле" true " proactor.

посмотреть AsyncrhonousSocketChannel, AsynchronousServerSocketChannel

и, если Java NIO поддерживает proactor обработка на основе ввода-вывода (либо в Java 6, либо Java 7) управляемый ОС асинхронный ввод-вывод поддержка (т. е. обратные вызовы завершения из ОС) используется?

чтение через JSR 203 спецификации, обработчики завершения с использованием новых асинхронных каналов определенно поддерживаются, и сообщается, что используются собственные функции ОС, но я еще не выяснил, в какой степени. Я могу следить за этим после анализа источника Java 7 (Если кто-то не бьет меня по нему).

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

Я не смог найти никаких сравнений производительности относительно новых асинхронных функций ввода-вывода в Java 7. Я уверен, что они станут доступны в ближайшем будущем.

Как всегда, когда представлено более одного способа решения проблемы, на вопросы о том, какой подход лучше, почти всегда отвечают "зависит". Проактивная обработка событий (с использованием асинхронного завершения обработчики) входит в Java 7 и не может просто существовать без цели. Для некоторых приложений имеет смысл использовать такую обработку ввода-вывода. Исторически общим примером, где proactor имеет хорошую применимость, является HTTP-сервер, где часто выдается много коротких запросов. Для более глубокого объяснения дайте это прочитать (предоставляется только для того, чтобы подчеркнуть преимущества proactor, поэтому старайтесь игнорировать тот факт, что пример кода-C++).

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

. . .

на боковой ноте я настоятельно рекомендую прочитать следующая презентация о NIO который предлагает сравнение производительности между NIO и" традиционным " подходом. Хотя я бы также посоветовал проявлять осторожность в отношении результаты, представленные как реализация NIO в бенчмарке, были основаны на библиотеке NIO pre Java 1.4 NBIO, а не на реализации NIO, поставляемой в 1.4.


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

блоки чтения, где нет данных для чтения. Это может быть большую часть времени. Однако блоки записи, когда буферы заполнены, это происходит очень редко и часто указывает на медленное соединение или неудачного потребителя.

Если вы хотите неблокирующего ввода-вывода, сделайте это для чтения,а также для записи.

Примечание: использование блокировки IO с NIO обычно проще и может выполнять неблокирующий NIO если у вас нет 1000 соединений, вы, вероятно, обнаружите, что добавленная сложность не стоит того. (И, возможно, не лучший вариант)


один из моих любимых шаблонов программного обеспечения книги (паттерн-ориентированное программное обеспечение Архитектура-шаблоны для параллельных и сетевые объекты)

в связи с тем, что эта книга очень устарела и имеет сомнительную актуальность в любое время. Она возникла в конце 1990-х годов, когда была предпринята целенаправленная попытка свести всю компьютерную науку к разработке моделей.

мой нынешний взгляд, НИО уже в рамках и шаблон проектирования.


NIO уже предоставляет реализацию реактивного шаблона (селекторы), и NIO2 добавляет реализацию упреждающего шаблона (обработчики завершения).

Не изобретайте его, просто используйте его, потому что вы не можете превзойти его производительность - это то, что любой, кто пытается избежать блокировки ввода - вывода, в конце концов-с чистым решением Java, поскольку вы не получаете доступ к неблокирующим/асинхронным функциям базовой ОС. Но NIO и NIO2 используют их, что делает их быстрыми.