[Javaの] BIOとNIOとAIO分析

.BIO NIOとAIOの概念

  BIOはブロッキングIOを同期しています

  NIOは同期非ブロッキングIO(NIO1.0、JDK1.4)

  AIOは、非同期ノンブロッキングIO(NIO2.0、JDK1.7)であります

二.BIO簡単な分析

  1.簡単な分析

    受け入れ、読みがブロックされるのでBIOは、IOをブロックしています。だから、シングルスレッドBIOは、同時実行を処理することができません。

  2.ケース

    サーバー:

クラス公開BioServer { 
    公共の静的な無効メイン(文字列[]引数)がスローにIOException { 
        ServerSocketを=新しい新規のServerSocket のServerSocketを(); 
        ServerSocket.bind(たInetSocketAddress新しい新規( "127.0.0.1"、9999 )); 
 バイト[] =新しい新しいバイトB [ 1024 ];  StringBuilderの新しい新しいSBは= のStringBuilderを(); System.out.printlnは( "......正しいサービスでの接続を待っている" );ソケットsocketAccept = serverSocket.accept(); //これはのSystem.outをブロックします。 println( "成功したクライアント接続" );ながら、(真の){System.out.printlnは( "メッセージを待つ......" );. socketAccept.getInputStream int型=読む()リード(B); //ここではそれはのSystem.out.println(「総読み取り」+ +読んで「バイト」ブロックします);文字列=新しい新しいSTRをストリング(B); sb.append(STR )のSystem.out.println( " データ内容が読み出され、" + SB);}}}

    クライアント:

パブリッククラスBioClient { 
    公共の静的な無効メイン(文字列[]引数)がスローにIOException { 
        ソケットのソケット=新しいソケット(); 
        スキャナスキャナ=新しいスキャナ(System.in)。 socket.connect(新規たInetSocketAddress( "127.0.0.1"、9999 ));  一方、(真){するSystem.out.println( "请输入内容" )。ストリング次= scanner.next()。。socket.getOutputStream()書き(next.getBytes()); }}}

    次のようにテストは以下のとおりです。

    

  3.マルチスレッド下BIO

    BIOは、マルチスレッドの同時治療ですが、頻繁には、あなたがスレッドを破棄、スレッドプールのスレッドの制限を使用することができたとしても、スレッド、および実行中のスレッドの数を(作成NIOに比べて間違いなく非常に資源集約的であるが、とき大規模な同時実行、BIOの道の効率または低すぎます)

    ここでは、マルチスレッドBIOケースは次のとおりです。

      サーバー:

パブリック クラスBioServerMultiThread {
     公共 静的 ボイドメイン(文字列[]引数)がスローにIOException { 
        ServerSocketをServerSocketを = 新しい新規のServerSocketを(); 
        ServerSocket.bind(新新たInetSocketAddress( "127.0.0.1"、9999 )); 
        のSystem.out.println(「サービス接続のための正しい待ち......「); 

        ながら、真の){ 
            ソケットsocketAccept = serverSocket.accept(); // これはブロックされます 
            のSystem.out.println(」クライアントの接続成功」); 

            新新しいスレッド(新しいです Runnableを(){
                @Override 
                公共 ボイドラン(){
                     しようと{ 
                        System.out.printlnは( "等待消息を......" )。
                        文字列のMSG = "" ;
                        一方、){
                             バイト [] B = 新しい バイト [1024 ];
                            INT LEN = socketAccept.getInputStream()(B)を読み取ります。
                            もし(LEN <0 ){
                                 続けます
                            }
                            MSG = 新しい文字列(B、0 、LEN)。
                            System.out.println(MSG)。
                        } 
                    } キャッチ(例外e){ 
                        e.printStackTrace(); 
                    } 
                } 
            }))(始めます。
        } 
    } 
}

      クライアント(複数のクライアント、同じコードを作成します):

パブリック クラスBioClient1 {
     公共 静的 ボイドメイン(文字列[]引数)がスローにIOException { 
        ソケットのソケット = 新しいソケット(); 
        スキャナスキャナ = 新しいスキャナ(System.in)。
        socket.connect(たInetSocketAddress( "127.0.0.1"、9999 )); 
        ストリングクラス名 = "这是来自" +にThread.currentThread()getStackTraceメソッド()[1] .getClassName()+ "的消息"。;
        一方、){ 
            するSystem.out.println( "请输入内容" )。
            文字列の横 =scanner.next(); 
            。socket.getOutputStream()書き(className.getBytes()); 
            。socket.getOutputStream()書き(next.getBytes()); 
        } 
    } 
}

      次のようにテストは以下のとおりです。

      

三の.NIO簡単な分析

  NIOは、非ブロッキングIOが、その理由は、データが、サーバへのセレクタによる通知準備ができていることであるが、データの準備が整う前に、待たずにサーバー。

  1.バッファ

    動作においてBIOは、すべてのデータがNIOで、バッファを操作するために使用され、流れ作業の形です。

    NIOバッファは、それがjava.nioのパッケージの下に抽象クラスのバッファクラスです、あなたは、次の図のように、JDKのAPIドキュメントの詳細を表示することができます

    

    オープンバッファクラスは、(メソッドがJDKのドキュメントを表示することが可能な)以下見ることができます

     

  2.直接および間接バッファバッファ

    ダイレクトバッファーが物理メモリに確立するために、バッファを指し、allocateDirectによって確立された方法(高効率が、安全ではありません)

    間接バッファは、方法割り当てによって確立されたJVM上に構築されたバッファを指す(低効率が、安全性)

  3.パイプライン

    NIOは、ブリッジ管路はjava.nioのパッケージ、例えば、JDKを参照して詳細については、APIドキュメント、図中のインタフェースであるデータを、送信しています。

    

  4.ファイルコピーを使用しNIOケースを達成するための2つの方法があり

    直接的な方法バッファ:

    @Test
    public void test1() throws IOException {
        long statTime=System.currentTimeMillis();
        //创建管道
        FileChannel   inChannel=    FileChannel.open(Paths.get("E://test/aaa.txt"), StandardOpenOption.READ);
        FileChannel   outChannel=    FileChannel.open(Paths.get("E://test/bbb.txt"), StandardOpenOption.READ,StandardOpenOption.WRITE, StandardOpenOption.CREATE);
        //定义映射文件
        MappedByteBuffer inMappedByte = inChannel.map(FileChannel.MapMode.READ_ONLY,0, inChannel.size());
        MappedByteBuffer outMappedByte = outChannel.map(FileChannel.MapMode.READ_WRITE,0, inChannel.size());
        //直接对缓冲区操作
        byte[] dsf=new byte[inMappedByte.limit()];
        inMappedByte.get(dsf);
        outMappedByte.put(dsf);
        inChannel.close();
        outChannel.close();
        long endTime=System.currentTimeMillis();
        System.out.println("操作直接缓冲区耗时时间:"+(endTime-statTime));
    }

    非直接缓冲区的方式:

 @Test
    public void test2() throws IOException {
        long statTime=System.currentTimeMillis();
        // 读入流
        FileInputStream fst = new FileInputStream("E://test/bbb.txt");
        // 写入流
        FileOutputStream fos = new FileOutputStream("E://test/ccc.txt");
        // 创建通道
        FileChannel inChannel = fst.getChannel();
        FileChannel outChannel = fos.getChannel();
        // 分配指定大小缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);
        while (inChannel.read(buf) != -1) {
            // 开启读取模式
            buf.flip();
            // 将数据写入到通道中
            outChannel.write(buf);
            buf.clear();
        }
        // 关闭通道 、关闭连接
        inChannel.close();
        outChannel.close();
        fos.close();
        fst.close();
        long endTime=System.currentTimeMillis();
        System.out.println("操作非直接缓冲区耗时时间:"+(endTime-statTime));
    }

  5.选择器(Selector)

    它是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel(通道)的状态是否处于可读、可写。如此可以实现单线程管理多个channels,也就是可以管理多个网络链接。使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销。详细用法可以参考JDK的API文档

    

四.AIO简单分析

  AIO(NIO2.0)和 NIO的主要区别是前者是异步的,而后者是同步的。

  同步:
    所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是事情必须一件一件地做,等前一件做完了才能做下一件事。
  异步:
    异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。

   与NIO不同,当进行读写操作时,AIO只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。  即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。

おすすめ

転載: www.cnblogs.com/ywb-articles/p/11108413.html