Подтвердить что ты не робот

Java Non-Blocking и Asynchronous IO с NIO & NIO.2 (JSR203) - Реактор/Проакторные реализации

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

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

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

Итак, мои вопросы: возможно ли использование IO на основе proactor в Java таким образом, что выгодно использовать для определенных сценариев; и, если Java NIO поддерживает поддержку ввода-вывода на основе proactor (либо на Java 6, либо на Java 7), используется ли поддержка асинхронного ввода-вывода под управлением ОС (то есть завершение обратных вызовов из ОС)? Более того, если реализация является чисто виртуальной в-ВМ, это настолько малоэффективно, что использование проактивной обработки событий предлагает не что иное, как другой (возможно, более простой) способ создания параллельного программного обеспечения для обработки сети.

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

4b9b3361

Ответ 1

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

Возможна ли обработка ввода-вывода на основе проактора в Java таким образом, что это выгодно использовать для конкретных сценарии.

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

Смотрите AsyncrhonousSocketChannel, AsynchronousServerSocketChannel

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

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

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

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

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

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

. , .

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

Ответ 2

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

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

Если вы хотите неблокировать IO, сделайте это для чтения, а также для записи.

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

Ответ 3

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

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

Мое настоящее представление состоит в том, что NIO уже является структурой и шаблоном проектирования.

Ответ 4

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

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