JAVA --IO/NIO モデル

目次

ブロッキング IO モデル

ノンブロッキングIOモデル

多重化IOモデル

信号駆動型 IO モデル

非同期IOモデル


ブロッキング IO モデル

        最も伝統的な IO モデルは、データの読み取りおよび書き込みのプロセス中にブロッキングが発生するというものです。ユーザー スレッドが IO リクエストを発行すると、カーネルはデータの準備ができているかどうかを確認し、準備ができていない場合はデータの準備ができるまで待機し、ユーザー スレッドをブロックして CPU を引き渡します。データの準備ができると、カーネルはデータをユーザー スレッドにコピーし、結果をユーザー スレッドに返します。その後、ユーザー スレッドはブロック状態を解放します。ブロッキング IO モデルの典型的な例は次のとおりです: data =ソケット.read(); データの準備ができていない場合、データは常に読み取りメソッドでブロックされます。

ノンブロッキングIOモデル

        ユーザー スレッドが読み取り操作を開始すると、待つ必要はなく、結果はすぐに取得されます。結果がエラーの場合は、データの準備がまだできていないことが分かるため、読み取り操作を再度送信できます。カーネル内のデータの準備が整い、ユーザー スレッドから再度リクエストを受信すると、すぐにデータをユーザー スレッドにコピーして戻ります。
実際、ノンブロッキング IO モデルでは、ユーザー スレッドはカーネルにデータの準備ができているかどうかを常に問い合わせる必要があります。つまり、ノンブロッキング IO は CPU を引き渡さず、常に CPU を占有します
一般的なノンブロッキング IO モデルは通常次のとおりです。

while(true){
data = socket.read();
if(data!= error){
处理数据
break;
}}

しかし、ノンブロッキング IO には非常に深刻な問題があります。while ループでは、カーネル データの
準備ができているほとんど使用されません。データを読み取ります。

多重化IOモデル

多重化 IO モデルは、現在最も一般的に使用されているモデルです。Java NIO は実際には多重化された IO です。多重 IO
モデルでは、複数のソケットのステータスを継続的にポーリングするスレッドが存在し、ソケットに実際に読み取りおよび書き込みイベントがある場合にのみ、
実際の IO 読み取りおよび書き込み操作が実際に呼び出されます。多重化 IO モデルでは、複数のソケットの管理に使用できるスレッドは 1 つだけであるため
、システムは新しいプロセスやスレッドを作成する必要も、これらのスレッドやプロセスを維持する必要もありません。また、実際の
ソケットの読み取りが行われた場合にのみ、 write events IO リソースは必要なときにのみ使用されるため、リソースの使用量が大幅に削減されます。Java NIO では、
selector.select() を使用して各チャネルに到着イベントがあるかどうかを問い合わせますが、イベントがない場合は常にそこでブロックされるため、このメソッドは
ユーザー スレッドをブロックします。多重 IO モードでは、複数のソケットを 1 つのスレッドで管理でき、
ソケットに実際に読み取りおよび書き込みイベントがある場合にのみ、実際の読み取りおよび書き込み操作のためにリソースが占有されます。
したがって、多重化 IO は、接続数が多い状況に適しています。

なお、多重化IOがノンブロッキングIOモデルよりも効率的である理由は、ノンブロッキングIOでは
ユーザースレッドを通じてソケットの状態を継続的に問い合わせるのに対し、多重化IOではソケットごとにポーリング状態が実行されるためです。この効率は
ユーザー スレッドの効率よりもはるかに高くなります。
ただし、多重 I​​O モデルでは、ポーリングを使用してイベントが到着したかどうかを検出し、
到着したイベントに 1 つずつ応答することに注意してください。そのため、多重化IOモデルでは、イベントレスポンスボディが大きくなると、その後のイベントが
長時間処理されなくなり、新たなイベントポーリングに影響が出る可能性があります。

信号駆動型 IO モデル

シグナル駆動型 IO モデルでは、ユーザー スレッドが IO リクエスト操作を開始すると、シグナル
関数ユーザー スレッドは実行を継続します。カーネル データの準備が整うと、シグナルが送信されます。シグナルを受信した後
、シグナル関数内で IO 読み取りおよび書き込み操作が呼び出され、実際の IO 要求操作が実行されます。

非同期IOモデル


非同期 IO モデルは最も理想的な IO モデルであり、ユーザー スレッドが読み取り操作を開始した後、すぐに他の処理を開始できます。一方、カーネルの観点から見ると、非同期読み取りを受信すると、
読み取り要求が正常に開始されたことを示す応答がすぐに返されるため、ユーザー スレッドに対してブロックは生成されません。次に、
カーネルはデータの準備が完了するのを待ってから、データをユーザー スレッドにコピーします。これがすべて完了すると、カーネルはユーザー スレッドに信号を送信して、読み取り操作が完了したことを伝えます
言い換えれば、ユーザー スレッドは IO 操作全体が実際にどのように
実行されるかを知る必要はありません。最初にリクエストを開始するだけで済みます。カーネルから返された成功シグナルを受信すると、IO 操作が完了したことを意味しますデータ
は直接使用できます。
つまり、非同期 IO モデルでは、IO 操作のどちらのフェーズもユーザー スレッドをブロックしません。両方のフェーズはカーネルによって自動的に完了し、操作が完了したことをユーザー スレッドに通知する信号が送信されます
特定の読み取りおよび書き込みのためにユーザー スレッドで IO 関数を再度呼び出す必要はありません
これはシグナル駆動モデルとは異なります。シグナル駆動モデルでは、ユーザー スレッドがシグナルを受信すると、データの
準備ができたことを示し、ユーザー スレッドは実際の読み取りと読み取りを実行するために IO 関数を呼び出す必要があります。書き込み操作。非同期 IO モデルでは、シグナルの受信は
IO 操作が完了したことを示し、実際の読み取りおよび書き込み操作のためにユーザー スレッドで IO 関数を呼び出す必要はありません。

非同期 IO には、オペレーティング システムによる基礎的なサポートが必要であることに注意してください。Java 7 では、非同期 IO が提供されます。

おすすめ

転載: blog.csdn.net/weixin_38340874/article/details/122086306