ホームページ Java &#&チュートリアル Java でノンブロッキング I/O を使用する方法

Java でノンブロッキング I/O を使用する方法

Sep 29, 2017 am 09:58 AM
java 説明書 について

この記事では主に Java でノンブロッキング I/O を使用する方法について説明します。また、ノンブロッキング I/O を使用してクライアントを実装する方法も示します。必要な場合はそれを参照できます。

ほとんどの知識と例は、O'REILLY の『Java Network Programming, Fourth Edition, by Elliotte Rusty Harold (O'REILLY)』から得ています。

ノンブロッキング I/O の概要

ノンブロッキング I/O (NIO) は、高い同時実行性を処理する手段です。同時実行性が高い場合、スレッドの作成とリサイクル、およびスレッド間の切り替えのオーバーヘッドが無視できなくなります。このとき、ノンブロッキング I/O テクノロジを使用できます。このテクノロジーの中心となるアイデアは、準備された接続を一度に選択し、その接続で管理できる限り多くのデータをできるだけ早く埋めてから、次の準備された接続に移動することです。

ノンブロッキングI/Oを使用して実装されたクライアント

通常、クライアントは多数の同時接続を処理する必要はありません。実際、ノンブロッキング I/O は主にサーバー向けに設計されていますが、クライアントでも使用できます。クライアントの設計はサーバーの設計よりも簡単であるため、以下の簡単なデモではクライアントを使用します。

まずchannelとバッファを紹介します。 SocketChannel クラスは、ノンブロッキング I/O で接続を作成するために使用されます。 SocketChannel オブジェクトを取得するには、SocketAddress オブジェクト (通常はそのサブクラス InetSocketAddress) をその静的ファクトリ メソッド open() に渡す必要があります。以下に例を示します。


SocketAddress address = new InetSocketAddress("127.0.0.1", 19);
SocketChannel client = SocketChannel.open(address);
ログイン後にコピー

open() メソッドはブロックしているため、これ以降のコードは接続が確立されるまで実行されません。接続を確立できない場合は、IOException がスローされます。

接続が確立されたら、入力と出力を取得する必要があります。従来の getInputStream() や getOutputStream() とは異なり、チャネルを使用すると、チャネル自体に直接書き込むことができます。バイト配列に書き込む代わりに、ByteBuffer オブジェクトが書き込まれます。 ByteBuffer オブジェクトは ByteBuffer.allocate(int Capacity) によって取得されます。Capacity はバイト単位のバッファ サイズです。ソケットから読み取られたデータがこのバッファに格納されます。 read() メソッドは、正常に読み取られてバッファに保存されたバイト数を返します。デフォルトでは、少なくとも 1 バイトを読み取るか、データの終わりを示す -1 を返し、使用可能なバイトがない場合はブロックします。これは、InputStream とほぼ同じように動作します。ただし、ノンブロッキング モードに設定されている場合、使用可能なバイトがない場合はすぐに 0 が返され、ブロックされません。


ここで、バッファー内に既にデータがあり、後でそれを抽出する必要があると仮定します。従来の方法を使用して、最初にデータをバイト配列に書き込み、次にそれを出力ストリームに書き込むことができます。これは完全にチャネルベースのメソッドです。Channels ツール クラスを使用して、出力ストリームをチャネルにカプセル化します。


ByteBuffer buffer = ByteBuffer.allocate(74);
ログイン後にコピー

上記のコードは、System.out をチャネルにカプセル化します。この後、出力を行うことができます。 ByteBuffer オブジェクトの各出力の前に、チャネルが最初から読み取りを開始できるように、その flip() メソッドを呼び出す必要があります。読み取りと書き込みの後、clear() メソッドを呼び出してバッファのステータスをリセットする必要があります。データ出力のコードは次のとおりです:


WritableByteChannel out = Channels.newChannel(System.out);
ログイン後にコピー

例 1: ノンブロッキング I/O を使用して実装された CharGenerator (文字ジェネレーター) クライアント


サーバー コード:

buffer.flip();
out.write(buffer);
buffer.clear();
ログイン後にコピー

クライアント コード:


public static void createCharGeneratorServer(){
  try(ServerSocket server = new ServerSocket(19)){
    while(true){
      try(Socket connection = server.accept()){
        OutputStream out = connection.getOutputStream();
        int firstPrintableCharacter = 33;
        int numberOfPrintableCharacter = 94;
        int numberOfCharactersPerLine = 72;
        int start = firstPrintableCharacter;
        while(true){
          for(int i = start ;
              i < start + numberOfCharactersPerLine ; i++){
            out.write
            (firstPrintableCharacter + (i - firstPrintableCharacter) % numberOfPrintableCharacter);
          }
          out.write('\r');
          out.write('\n');
          start = firstPrintableCharacter + (start + 1 - firstPrintableCharacter) % numberOfPrintableCharacter;
        }
      }catch (IOException e) {
        e.printStackTrace();
      }
    }
  } catch (IOException e) {
    e.printStackTrace();
  }
}
ログイン後にコピー

ノンブロッキングモードを有効にする


上記のプログラムは、入出力ストリームを使用する従来の方法とあまり変わりません。ただし、ServerSocket の configureBlocking(false) メソッドを呼び出して非ブロッキング モードに設定することができます。このモードでは、利用可能なデータがない場合、read() メソッドはすぐに戻り、クライアントは他のことを行うことができます。ただし、データを読み取れない場合、read() メソッドは 0 を返すため、データを読み取るループにいくつかの変更を加える必要があります。

以上がJava でノンブロッキング I/O を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Javaの平方根

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Javaの完全数

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーター

Javaのアームストロング数 Javaのアームストロング数 Aug 30, 2024 pm 04:26 PM

Javaのアームストロング数

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

ジャワのウェカ

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Javaのスミス番号

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

Java Springのインタビューの質問

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8 Stream Foreachから休憩または戻ってきますか?

See all articles