ハイエンドの建築家の概要のアリ十年:5つの方法は、Java NIOとNIO.2を最大にするために、

JavaNIO目的は、JavaプラットフォームでのプログラミングI / O集中型の雑用を改善することです。10年後、多くのJavaプログラマはまだNIOを最大限に活用する方法がわからない、さらに少ない人は、Java SE 7が導入を認識している以上、新たな入力/出力API(NIO.2)。このチュートリアルでは、NIOパッケージとNIO.2共通Javaプログラミングシーンの利点を実証5簡単な例を見つけることができます。ハイエンドの建築家の概要のアリ十年:5つの方法は、Java NIOとNIO.2を最大にするために、

入力/出力処理:JavaプラットフォームにNIOとNIO.2主要な寄与はでJavaアプリケーション開発の性能を改善するために、コア領域の一つです。各Java I / Oのシナリオは、新たな入力/出力APIのどちらかのバージョンが特に使いやすいではありません必要はありません。しかし、正しい使用のJava NIOは、時間を節約することができますし、NIO.2にはいくつかの共通のI / Oは動作に必要。これは、NIOとNIO.2超能力です。
この記事では、それらを使用する5つの比較的単純な方法を説明します。
変更の通知(誰もが観客を必要とするため)
ヘルプ多重選択するために
チャンネルを-約束と現実の
メモリマッピング-基本的な
文字エンコーディングと検索
NIO環境を
しています10歳は、まだ新しい入力/出力バッグのJavaの強化のですか?その理由は、Javaが十分な基本的なJava I / O操作の面で多くの作業をプログラマということです。ほとんどの開発者は、日々の仕事のためのJava NIOを習得する必要はありません。また、NIOは、単にパフォーマンスキットではありません。むしろ、それは、関連するJava I / O機能の異種のコレクションです。NIO「近いJavaプログラムを」NIOとNIO.2 APIは、低レベルのシステムのオペレーティングシステム(OS)のエントリポイントを開示している意味するJavaアプリケーションのパフォーマンスを改善するためにスルー。NIOのトレードオフは、それはまた、私たちはより良いI / Oを制御することができ、及びOのプログラミングは、基本的なI.より慎重である/私たちを尋ねたということです 懸念のもう一つの側面は、我々は、その後の練習のいくつかでそれを使用しますが、そのアプリケーションのNIOの表現力です。
多くの開発者のために、保守作業時の最初の出会いのNIOことがありますアプリケーションが正しい機能を持っていますが、それはそれを加速するためにNIOを使用することが示唆されたので、応答は、非常に遅いです。その光のためのNIOは、処理パフォーマンスを向上させることができ、その結果は密接に基礎となるプラットフォームに関連付けられます。(してくださいノート、NIOプラットフォームに依存する。)あなたが初めてNIOしている場合、それは慎重に測定する必要がします。あなたも、アプリケーションのパフォーマンスがオペレーティングシステム上ではなく、特定のJVM、ホストの仮想化コンテキストにのみ依存するものではなく、大容量のデータ保存特性を加速するNIOの能力を見つけることができます。しかし、総括尺度は注意が必要です。念頭に置いて、あなたの目標は、展開を移動する場合は特に。
さて、言うまでもなく、私たちはNIOとNIO.5の5つの重要な機能を探検してみましょう。
1.変更通知(誰もが観客を必要とするため)
、Javaアプリケーションプログラムのパフォーマンスは、共通のNIOへの魅力や開発者のNIO.2の関心です。しかし、私の経験では、NIO.2ファイル変更通知プログラムは、新しい入力/出力APIは(あまり人気であれば)最も魅力的です。
次の例では、多くのエンタープライズアプリケーションは、特定のアクション取る必要がある
FTPフォルダにアップロードファイルを
構成定義は変更されている
ドラフト文書が更新されました
別のファイルシステムイベントの
これらの変化の例を変更通知に対応していますか。Javaの(および他の言語)の初期のバージョンでは、ポーリングは、通常のイベントの変化を検出するための最良の方法です。ポーリングは、無限ループの特別な種類です:何も変化がない場合には、後に(例えば、百ミリ秒または10秒)短い間隔で再確認してください、最後の既知の状態と比較することができ、ファイル・システムまたはその他のオブジェクトをチェックしてください。サイクルは無期限に継続されます。
NIO.2は、私たちは、検出の方法を変更するためのよりよい表現を提供します。リスト1は、簡単な例です。
通知1. NIO.2チェンジリスト
のインポートjava.nio.file.attributeを。;
輸入java.io.
;
輸入java.utilの。*;
輸入java.nio.file.Path;
輸入java.nio.file.Paths。
輸入java.nio.file.StandardWatchEventKinds。
輸入java.nio.file.WatchEvent;
輸入java.nio.file.WatchKey。
輸入java.nio.file.WatchService;
輸入はjava.util.List;

パブリッククラスウォッチャー{
パブリック静的無効メイン(文字列[] args){
パスTHIS_DIR = Paths.get( "")。
System.out.println(「今、現在のディレクトリを見て...」);

      try {
          WatchService watcher = this_dir.getFileSystem().newWatchService();
          this_dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);

          WatchKey watckKey = watcher.take();

          List<WatchEvent< &64;>> events = watckKey.pollEvents();
          for (WatchEvent event : events) {
              System.out.println("Someone just created the file '" + event.context().toString() + "'.");

         }

     } catch (Exception e) {
         System.out.println("Error: " + e.toString());
     }
  }

}
このソースをコンパイルして、コマンドライン実行可能ファイルを起動します。同じディレクトリには、新しいファイルを作成します。たとえば、あなたもWatcher.classの例1をコピーする例1に触れる可能性があります。あなたは、通知メッセージに次の変更が表示されるはずです
。ただ、ファイルの作成「例1」での誰かが、
この単純な例では、言語機能へのJava NIOへのアクセスの使用を開始する方法を示しています。また、従来のポーリングベースのI、変更通知のために使いやすくよりも直接的に対応するクラス/ OソリューションをNIO.2ウォッチャークラスについて説明します。
使用上の注意
、それはニーズ分析を見落とすことは容易であるので、前回のポーリングサイクルよりも使用するNIOの通知手順はるかに簡単に、。あなたが最初のリスナーを使用する場合しかし、あなたは慎重にこれらのセマンティクスを考慮する必要があります。例えば、より有用な修正を開始するタイミングを知るよりも、ファイルの変更の際に端を知ります。特に、このような一般的なFTPのドロップフォルダの場合には、注意するために、この分析が必要。NIOは、いくつかの微妙含ま強力なソフトウェアパッケージである「トラップを。」これは、招かれざる客を罰することができます。
2.選択して、非同期I / O:マルチプレクサセレクタのヘルプ
初心者にはなり時々 NIOに関連付けられている「ノン・ブロッキングI / O」。NIOだけではないI / Oを非ブロックが、エラーは理にかなって:Javaの基本的なI / Oがブロックされている-それは操作が完了するまで待つことができることを意味し-と、非ブロッキングまたは非同期I / Oが最も一般的に使用されます1件のNIO施設。
NIO非ブロッキングI / Oイベント・ベースの、そのようなリスト1に示すように、聴取者のファイルシステムとして。この手段は、I / Oチャネルのセレクタ(またはコールバックまたはリスナー)を定義し、処理を継続します。イベントが(例えば、ライン入力到着)セレクタに発生した場合、セレクタは「ウェイクアップ」して実行します。これらの全ては、典型的なJavaのI / Oと全く対照的であるシングルスレッドで実装されています
リスト2は、(参考文献を参照)マルチポートネットワークエコーERにおけるNIOセレクタの使用を示し、手順はわずかに変更、2003年グレッグ・トラビスと同様に作成されます。UnixやUnixライクなオペレーティングシステムは長いので、Javaプログラムのための手順をコーディングするこのネットワークは良好なパフォーマンスのネットワークモデルで、セレクタを達成するために有効でした。
2. NIOセレクタリスト
のインポートjava.io.を
インポートjava.net。
;
インポートjava.nioのは
インポートはjava.nio.channelsのこと。
;
java.utilのインポートクラスは、*;

パブリッククラスMultiPortEcho
{
プライベートINTポート[]。
民間のByteBuffer echoBuffer = ByteBuffer.allocate(1024);

public MultiPortEcho( int ports[] ) throws IOException {
  this.ports = ports;

  configure_selector();
}

private void configure_selector() throws IOException {
  // Create a new selector
  Selector selector = Selector.open();

  // Open a listener on each port, and register each one
  // with the selector
  for (int i=0; i<ports.length; ++i) {
    ServerSocketChannel ssc = ServerSocketChannel.open();
    ssc.configureBlocking(false);
    ServerSocket ss = ssc.socket();
    InetSocketAddress address = new InetSocketAddress(ports[i]);
    ss.bind(address);

    SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT);

    System.out.println("Going to listen on " + ports[i]);
  }

  while (true) {
    int num = selector.select();

    Set selectedKeys = selector.selectedKeys();
    Iterator it = selectedKeys.iterator();

    while (it.hasNext()) {
      SelectionKey key = (SelectionKey) it.next();

      if ((key.readyOps() & SelectionKey.OP_ACCEPT)
        == SelectionKey.OP_ACCEPT) {
        // Accept the new connection
        ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
        SocketChannel sc = ssc.accept();
        sc.configureBlocking(false);

        // Add the new connection to the selector
        SelectionKey newKey = sc.register(selector, SelectionKey.OP_READ);
        it.remove();

        System.out.println( "Got connection from "+sc );
      } else if ((key.readyOps() & SelectionKey.OP_READ)
        == SelectionKey.OP_READ) {
        // Read the data
        SocketChannel sc = (SocketChannel)key.channel();

        // Echo data
        int bytesEchoed = 0;
        while (true) {
          echoBuffer.clear();

          int number_of_bytes = sc.read(echoBuffer);

          if (number_of_bytes <= 0) {
            break;
          }

          echoBuffer.flip();

          sc.write(echoBuffer);
          bytesEchoed += number_of_bytes;
        }

        System.out.println("Echoed " + bytesEchoed + " from " + sc);

        it.remove();
      }

    }
  }
}

static public void main( String args[] ) throws Exception {
  if (args.length<=0) {
    System.err.println("Usage: java MultiPortEcho port [port port ...]");
    System.exit(1);
  }

  int ports[] = new int[args.length];

  for (int i=0; i<args.length; ++i) {
    ports[i] = Integer.parseInt(args[i]);
  }

  new MultiPortEcho(ports);
}

}
次に呼び出すか、のように、Java(登録商標)MultiPortEcho 8005として8006は、コマンドラインから起動、このソースコードをコンパイル。MultiPortEchoerたら、ポート8005および8006上の簡単なtelnetまたは他の端末エミュレータを実行するために実行します。あなたは、受信した番組エコーの文字が表示されます-と、単一のJavaスレッドで完成します!
3.チャンネル:約束と現実
NIOで、チャネルは、任意のオブジェクトが読み書きできることができます。その仕事は抽象ファイル、ソケットにあります。NIOチャネルは、特別な事情なしにネットワークに係る他のチャンネルまたはプログラムに接続することができ、方法の一貫したセットをサポートし、実際に使用される標準出力。フローチャネルのシェアのJavaの基本的なI / O特性。ブロックI / Oストリーム、I / Oを非同期チャネルのサポート
NIOが、そのパフォーマンス上の利点としばしば主張しますが、より正確に、それは高い応答性を持っています。いくつかのケースでは、基本的なJava I / O性能より実際に悪いNIO。例えば、単純な読み取りと書き込みのファイルに対して順次小さく、より単純な実装は、対応する二重または三重イベント指向チャネルベースの符号化よりも速く流れることができます。同様に、非多重化されたチャネル(すなわち、チャネル別のスレッド)はるかに遅いにおける単一スレッドチャネルセレクタ・レジスタよりもできます。
あなたが必要とするか、または問題を定義するためのチャネルプログラムのサイズは、以下の質問をしようとすると、フローに関連する次の時間:
I / Oの数は、読み取りおよび書き込みしなければならないことをオブジェクト?
私は自然な順序間で異なるがある場合、/ Oは、オブジェクト、または彼らが発生する必要がありますか?
あなたのI / Oオブジェクトはほんの短い時間間隔を持続している、またはにおけるライフコースを通じて持続可能?
それは単一のスレッドまたは複数の異なるスレッドで、より自然であるかどうかをI / Oを実行しますか?
ネットワークトラフィックは同じローカルIに/ Oを見えるかもしれません、またはその両方が異なるモードがありますか?
この分析は、良い練習のストリームまたはチャネルを使用するかを決定することです。注意:NIOとNIO.2は、基本的なI / Oを置き換えることはできません。彼らはそれを補完します。
4.メモリマッピング-重要な場所
NIOを使用して、最も安定したパフォーマンスが大幅に改善されたメモリマップに関するものです。メモリマッピングは、メモリ領域として、プログラミングの目的のために、ファイルのどの部分が表示されることができ、オペレーティングシステムレベルのサービスです。
私は多くを紹介するためにここにいるよりも多くのメモリマップされた結果と意味があります。高い観点からは、ファイルへのアクセスが発生するのではなくメモリへのI / Oの高速アクセスを行うことができます。前者は後者より速く、通常は二桁です。図3に示すメモリマッピング機能をリストNIOの最小です。
リスト3. NIOののメモリマップ
のインポートのjava。IO。AのRandomAccessFile; Javaソースコードの読み込み。NIO。AれるMappedByteBuffer; Javaソースコードの読み込み。NIO。チャンネル。FileChannel。

公共类mem_map_example { 私有静态整数mem_map_size = 20 * 1024 * 1024 ; 私有静态字符串fn = “ example_memory_mapped_file.txt” ; 

  公共静态无效主体(字符串[] args )抛出异常{ RandomAccessFile memoryMappedFile = new RandomAccessFile (fn ,“ rw” );     

      //映射文件到存储器MappedByteBuffer 出= memoryMappedFile 。getChannel ()。映射(FileChannel 。MapMode 。READ_WRITE ,0 ,mem_map_size );

      //写入内存映射文件对(INT 我= 0 ; 我< mem_map_size ; 我++){ 出来。放((byte )'A' ); } 系统。出来。的println (“文件'” + FN + “'现在是” + 整数。的toString (mem_map_size )+ “字节满”。);

      //从内存映射文件读取。for (int i = 0 ; i < 30 ; i ++){ 系统。出来。打印((焦炭)了。让(我)); } 系统。出来。println (“ \ n从内存映射文件'” + fn + “' 读取完成。” ); } }

example_memory_mapped_file.txt文字Aファイルで満たされ、ファイルの最初の30のバイトを読んで、すぐに20メガバイトのファイルを作成するための3つの小さなモデルリスト。実際には、メモリ・マップは、生の高速I / Oのためだけでなく、非常に興味深いですが、また、いくつかの異なるリーダライタは、同じファイルの画像生じた懸念に同時に接続することができるからです。危険への技術十分に強いが、適切に使用されている場合、それは非常に高速な実装を実現することができます。ウォールストリートの取引事業はうまく競合他社が、でも、ミリ秒を秒を取得するように、メモリマッピングを使用することが知られています。
5.文字エンコーディングの検索や
、私がこの記事で紹介したいと思いますが、最終的な機能NIOの文字セット、異なる文字エンコーディング間の変換のためのパッケージです。でもNIO前に、Javaのこのメソッドを介してGetBytesメソッドは、同じ機能の多くを構築しました。それは、アーキテクチャレベルで優れた性能が得られ、より柔軟で実装が簡単で、比較的低いGetBytesメソッドであるため、文字セットは、しかし、我々は、それを使用することを歓迎します。これは、英語と区別する検索の他の機能以外の言語での照合コード化することが特に重要です。
ネイティブJava Unicode文字エンコーディングから図4の遷移をリストラテン1の例です。
エンコード4. NIO文字リスト
文字列some_stringを= "これは、A列のJavaネイティブに格納したUnicodeのASです。";
文字セットlatin1_charset = Charset.forName( "ISO-8859-1");
CharsetEncode latin1_encoder charset.newEncoder =();
ByteBufferのlatin1_bbuf = latin1_encoder.encode(CharBuffer.wrap(some_string ))。
メモ、文字セットのチャネル及びプログラムメモリマップとの間の連携を必要とする、非同期I / O変換及び符号化を十分に行うことができることを確実にするために、よく一緒に動作するように設計。
最後に、非常に多くの年の開発は、私がデータやインタビューの質問を要約しているあなたは、あなたが私に従うことができる上に自社の技術をアップグレードしたい場合は、Javaの学習、私的な手紙は、その連絡先の詳細を残すための情報やコメントエリアを受けるために送信され、時間より多くの人々がああを見て、私は前方の下にポイントを作るために覚えています。ハイエンドの建築家の概要のアリ十年:5つの方法は、Java NIOとNIO.2を最大にするために、

おすすめ

転載: blog.51cto.com/14606566/2466065