弊社の一般的な IO モデルには、ブロッキング IO モデル、ノンブロッキング IO モデル、多重化 IO モデル、シグナルドリブン IO モデル、非同期 IO モデルが含まれます。以下では、上記の IO モデルを簡単に紹介します。
#1. ブロッキング IO モデル
最も伝統的な IO モデル、つまり、ブロッキングは読み取りと読み取りのプロセス中に発生します。データを書き込む現象。ユーザー スレッドが IO リクエストを発行すると、カーネルはデータの準備ができているかどうかを確認し、準備ができていない場合はデータの準備ができるまで待機し、ユーザー スレッドをブロックして CPU を引き渡します。データの準備ができると、カーネルはデータをユーザー スレッドにコピーし、結果をユーザー スレッドに返します。その後、ユーザー スレッドはブロック状態を解放します。ブロッキング IO モデルの典型的な例は次のとおりです: data =ソケット.read(); データの準備ができていない場合、データは常に読み取りメソッドでブロックされます。
2. ノンブロッキング IO モデル
ユーザー スレッドが読み取り操作を開始すると、待つ必要はなく、結果はすぐに取得されます。結果がエラーの場合は、データの準備がまだできていないことが分かるため、読み取り操作を再度送信できます。カーネル内のデータの準備が整い、ユーザー スレッドから再度リクエストを受信すると、すぐにデータをユーザー スレッドにコピーして戻ります。実際、ノンブロッキング IO モデルでは、ユーザー スレッドはカーネルにデータの準備ができているかどうかを常に問い合わせる必要があります。つまり、ノンブロッキング IO は CPU を引き渡さず、常に CPU を占有します。典型的なノンブロッキング IO モデルは一般に次のとおりです:
while(true){ data = socket.read(); if(data!= error){ 处理数据 break; } }
しかし、ノンブロッキング IO には非常に深刻な問題があります。while ループでは、カーネル データの準備ができているかどうかを常に確認する必要があります。 CPU 使用率が非常に高くなるため、一般に while ループがデータの読み取りに使用されることはほとんどありません。
3. 多重化 IO モデル
多重化 IO モデルは、現在最も一般的に使用されているモデルです。
Java NIO は実際には多重化された IO です。多重 IO モデルでは、複数のソケットのステータスを継続的にポーリングするスレッドが存在し、ソケットに実際に読み取りおよび書き込みイベントがある場合にのみ、実際の IO 読み取りおよび書き込み操作が実際に呼び出されます。
多重化 IO モデルでは、複数のソケットの管理に使用できるスレッドは 1 つだけであるため、システムは新しいプロセスやスレッドを作成する必要も、これらのスレッドやプロセスを維持する必要もありません。実際の IO リソースはソケットの読み取りおよび書き込みイベントがある場合にのみ使用されるため、リソースの使用量が大幅に削減されます。
Java NIO では、各チャネルの到着イベントがあるかどうかを問い合わせるために selector.select() が使用されます。イベントがない場合は常にそこでブロックされるため、このメソッドではユーザー スレッドが発生します。封鎖する。
多重 IO モードでは、複数のソケットを 1 つのスレッドで管理できます。ソケットに実際に読み取りおよび書き込みイベントがある場合にのみ、実際の読み取りおよび書き込み操作のためにリソースが占有されます。したがって、多重化 IO は、接続数が多い状況に適しています。
さらに、多重化 IO がノンブロッキング IO モデルよりも効率的である理由は、ノンブロッキング IO ではユーザー スレッドを通じてソケットのステータスが常に問い合わせられるのに対し、多重化 IO ではユーザー スレッドをポーリングするためです。各ソケットのステータスはカーネルによって実行され、この効率はユーザー スレッドの効率よりもはるかに高くなります。
ただし、多重 IO モデルでは、ポーリングを使用してイベントが到着したかどうかを検出し、到着したイベントに 1 つずつ応答することに注意してください。そのため、多重化IOモデルでは、イベントレスポンスボディが大きくなると、その後のイベントが長時間処理されなくなり、新たなイベントポーリングに影響が出る可能性があります。
4. シグナル駆動型 IO モデル
シグナル駆動型 IO モデルでは、ユーザー スレッドが IO リクエスト操作を開始すると、シグナル関数が登録されます。対応するソケットに接続され、ユーザー スレッドは実行を継続します。カーネル データの準備が完了すると、シグナルがユーザー スレッドに送信されます。シグナルを受信した後、ユーザー スレッドはシグナル関数で IO 読み取りおよび書き込み操作を呼び出します。実際の IO リクエスト操作を実行します。
5. 非同期 IO モデル
非同期 IO モデルは、最も理想的な IO モデルです。非同期 IO モデルでは、ユーザー スレッドが読み取り操作を開始すると、すぐに他のことを始めることができます。
一方、カーネルの観点から見ると、非同期読み取りを受信すると、読み取りリクエストが正常に開始されたことを示す応答がすぐに返されるため、ユーザー スレッドに対してブロックは生成されません。
その後、カーネルはデータの準備が完了するのを待ち、データをユーザー スレッドにコピーします。これがすべて完了すると、カーネルはユーザー スレッドにシグナルを送信して次のことを伝えます。読み取り操作が完了します。言い換えれば、ユーザー スレッドは IO 操作全体が実際にどのように実行されるかを知る必要はありません。最初にリクエストを開始することだけが必要です。カーネルから返された成功シグナルを受信すると、IO 操作が完了したことを意味します。データは直接使用できます。
つまり、非同期 IO モデルでは、IO 操作のどちらのフェーズもユーザー スレッドをブロックしません。どちらのフェーズもカーネルによって自動的に完了し、ユーザー スレッドにそれを通知する信号が送信されます。操作は完了しました。特定の読み取りおよび書き込みのためにユーザー スレッドで IO 関数を再度呼び出す必要はありません。
これはシグナル駆動モデルとは異なります。シグナル駆動モデルでは、ユーザー スレッドがシグナルを受信すると、データの準備ができたことを示し、ユーザー スレッドは IO 関数を呼び出して次の処理を実行する必要があります。実際の読み取りおよび書き込み操作、非同期 IO モデルでは、シグナルの受信は IO 操作が完了したことを示し、実際の読み取りおよび書き込み操作を実行するためにユーザー スレッドで IO 関数を呼び出す必要はありません。
非同期 IO には、オペレーティング システムの基礎となるサポートが必要であることに注意してください。Java 7 では、非同期 IO が提供されます。
以上がJAVA の一般的な IO/NIO モデルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。