web-dev-qa-db-ja.com

Javaノンブロッキングおよび非同期IO with NIO&NIO.2(JSR203)-リアクター/プロクターの実装

だからここで私は私のお気に入りのソフトウェアパターンブックの1つ(パターン指向ソフトウェアアーキテクチャ-並行オブジェクトとネットワークオブジェクトのパターン)、特にProactor/Reactor非同期IOパターンのセクションを読んでいます。選択可能なチャネルを使用することで、Reactorスタイルの非同期IOメカニズムを非常に簡単に実装できる(そして実装した)方法がわかります。しかし、ノンブロッキング書き込みで適切なProactorメカニズムを実装する方法がわかりません。これは、OSが管理するノンブロッキング書き込み機能を利用しています。

Win32で GetQueuedCompletionStatus のようなOS固有の呼び出しでサポートされる機能。

Java 7は、非同期完了ハンドラー(正しい方向にあるようです)を使用してNIOにいくつかの更新をもたらすことを確認しました。そうは言っても... OS管理の非同期操作(特に非同期書き込み)に対する統合されたクロスプラットフォームサポートがないことを考えると、これはネイティブOSサポートを利用していない厄介な実装であると思います。

だから私の質問は、特定のシナリオに使用するのに有利な方法で、IOでプロクターベースのJava処理が可能かどうかです。また、JavaNIOがプロクターベースのIO処理(Java6またはJava 7のいずれか)をサポートしている場合、OSで管理される非同期IOサポート(つまり、OSからの完了コールバック)が利用されていますか?さらに、実装が純粋にVM内にある場合、パフォーマンス上の利点はほとんどないため、プロアクティブなイベント処理を使用しても、同時ネットワーク処理ソフトウェアを構築するための異なる(おそらくより単純な)方法にすぎません。

プロアクティブなイベント処理に関心のある人のために ここに良い記事があります 長所/短所の概要と、従来の接続ごとのスレッドモデルとリアクティブIOモデルの両方との比較。

26
S73417H

これには多くの要因が関係しています。私は自分の発見を可能な限り要約しようと思います(リアクターとプロクターの有用性に関して論争があるという事実に注意してくださいIO実装の処理)。

プロクターベースのIO処理はJavaで可能であり、特定のシナリオで使用するのに有利です。

Java1.4は非ブロッキングを導入しましたIOこれは非同期IOと同じではありません。Java SE7は非同期IO with 「真の」プロクタースタイルを可能にするJSR203 IO実装の処理を可能にします。

AsyncrhonousSocketChannelAsynchronousServerSocketChannel を参照してください

そして、Java NIOがプロクターベースのIO処理をサポートしている場合(Java 6またはJava 7)OS管理の非同期IOサポート(つまり、OSからの完了コールバック)が利用されていますか?

JSR 203の仕様を読むと、新しい非同期チャネルを使用した完了ハンドラーが確実にサポートされており、ネイティブOS機能が使用されていると報告されていますが、どの程度かはまだわかりません。 Java 7ソースを分析した後(誰かが私を殴らない限り)、これをフォローアップするかもしれません。

さらに、実装が純粋にVM内にある場合、パフォーマンス上の利点はほとんどないため、プロアクティブなイベント処理を使用しても、同時ネットワーク処理ソフトウェアを構築するための異なる(おそらくより単純な)方法にすぎません。

新しい非同期IO機能Java 7。でパフォーマンスの比較を見つけることができませんでした。近い将来利用可能になると確信しています。

いつものように、問題に取り組むための複数の方法が提示された場合、どちらのアプローチが優れているかという質問には、ほとんどの場合「依存」で答えられます。プロアクティブなイベント処理(非同期完了ハンドラーを使用)はJava 7に含まれており、目的なしに単純に存在することはできません。特定のアプリケーションでは、このようなIO =処理。歴史的に、proactorの適用性が高い一般的な例は、多くの短いリクエストが頻繁に発行されるHTTPサーバーです。詳細な説明については これを読んでください (proactorの利点を強調するためにのみ提供されています)したがって、サンプルコードがC++であるという事実を見落としてみてください。

IMOは、多くの状況で、リアクター/プロクターが、従来のアプローチを使用した非常に単純な設計を複雑にし、他のより複雑なシステムでは、高度な簡素化と柔軟性を提供することは明らかです。

。 。 。

ちなみに、NIOと「従来の」アプローチのパフォーマンス比較を提供する NIOに関する次のプレゼンテーション を読むことを強くお勧めします。ベンチマークでのNIO実装は、1.4で出荷されたNIO実装ではなく、pre Java 1.4 NBIO NIOライブラリに基づいているため、提示された結果についても注意が必要です。

22
S73417H

書き込みのブロックについて本当に心配する必要があるかどうかを確認します。

読み取るデータがない読み取りブロック。これはほとんどの場合です。ただし、バッファがいっぱいになると書き込みがブロックされます。これは非常にまれに発生し、接続が遅いか、コンシューマに障害が発生したことを示していることがよくあります。

ノンブロッキングIOが必要な場合は、読み取りに対しても実行し、書き込みに対しても実行します。

注:NIOでブロッキングIOを使用する方が通常は簡単で、数千の接続がない限り非ブロッキングNIOを実行できますが、追加された複雑さはそれだけの価値がないことに気付くでしょう。おそらく最良の選択肢ではありません)

8
Peter Lawrey

NIOはすでにリアクティブパターンの実装を提供しています(セレクター)、そして NIO2はの実装を追加しますプロアクティブパターン (完了ハンドラー)。

純粋なJavaソリューションを使用すると、I/Oのブロックを回避しようとする人は結局のところ、パフォーマンスに勝るものはありません。基盤となるOSの非ブロッキング/非同期機能にアクセスしないでください。ただし、NIOとNIO2はこれらを利用するため、高速になります。

2

私のお気に入りのソフトウェアパターンブックの1つ(パターン指向のソフトウェアアーキテクチャ-同時およびネットワークオブジェクトのパターン)

その本に関しては、非常に時代遅れであり、どの日付でも関連性が疑わしいものです。それは、コンピュータサイエンス全体をデザインパターンに還元しようという協調的な試みがあった1990年代後半のデザインパターン狂乱から生まれました。

私の現在の見解は、NIOはすでにフレームワークとデザインパターンであるということです。

2
user207421