26

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

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

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

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

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

4

4 に答える 4

23

これには多くの要因が関係しています。私は自分の調査結果を可能な限り要約するように努めます(リアクターとプロクターのIO処理の実装の有用性に関して競合があるという事実を認識しています)。

特定のシナリオで使用するのに有利な方法で、JavaでプロクターベースのIO処理が可能ですか。

Java 1.4では、非同期IOとは異なる非ブロッキングIOが導入されました。Java SE 7では、JSR203を使用した非同期IOが導入され、「真の」プロクタースタイルのIO処理の実装が可能になります。

AsyncrhonousSocketChannelAsynchronousServerSocketChannelを参照してください

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

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

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

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

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

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

。。。

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

于 2011-04-05T12:33:20.853 に答える
9

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

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

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

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

于 2011-04-03T15:41:48.230 に答える
2

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

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

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

于 2011-04-05T09:00:11.870 に答える
2

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

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

于 2015-05-27T02:18:44.430 に答える