[Java] BIO and NIO and AIO analysis

.BIO a concept of the NIO and AIO

  BIO is a synchronous blocking IO

  NIO is synchronous non-blocking IO (NIO1.0, JDK1.4)

  AIO is asynchronous nonblocking IO (NIO2.0, JDK1.7)

Two .BIO simple analysis

  1. Simple analysis

    BIO is blocking IO, because accept and read will block. So single-threaded BIO is unable to handle concurrency.

  2. Case

    Server:

class public BioServer { 
    public static void main (String [] args) throws IOException { 
        the ServerSocket = new new serverSocket the ServerSocket (); 
        ServerSocket.bind (the InetSocketAddress new new ( "127.0.0.1", 9999 )); 
 byte [] = new new byte B [ 1024 ];  the StringBuilder new new SB = the StringBuilder (); System.out.println ( "waiting for connection in the correct service ......" ); the Socket socketAccept = serverSocket.accept (); // this will block System.out. println ( "client connection successful" ); the while (to true ) {System.out.println ( "wait message ......" );. socketAccept.getInputStream int = Read () Read (B); // here it will block System.out.println ( "total read" + read + "bytes" ); String = new new STRString (b); sb.append (str ); System.out.println ( " data content is read:" + SB);}}}

    Client:

public class BioClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        Scanner scanner = new Scanner(System.in);
        socket.connect(new InetSocketAddress("127.0.0.1",9999));
        while(true){ System.out.println("请输入内容"); String next = scanner.next(); socket.getOutputStream().write(next.getBytes()); } } }

    Tests are as follows:

    

  BIO under 3. Multithreading

    BIO is multithreaded concurrent treatment, but frequent create threads, and the number of threads running (even if you can use the thread pool thread limit destroying threads is undoubtedly a very resource-intensive, but when massive concurrency, the efficiency of BIO way compared to NIO or too low)

    Here is a multithreaded BIO Case:

      Server:

public  class BioServerMultiThread {
     public  static  void main (String [] args) throws IOException { 
        the ServerSocket serverSocket = new new the ServerSocket (); 
        ServerSocket.bind ( new new the InetSocketAddress ( "127.0.0.1", 9999 )); 
        System.out.println ( "Service correct waiting for connection ...... " ); 

        the while ( to true ) { 
            the Socket socketAccept = serverSocket.accept (); // this will block 
            System.out.println (" client connection success " ); 

            new new the Thread ( new new the Runnable () {
                @Override
                public void run() {
                    try{
                        System.out.println("等待消息......");
                        String msg = "";
                        while (true){
                            byte[] b = new byte[1024];
                            int len = socketAccept.getInputStream().read(b);
                            if (len < 0){
                                continue;
                            }
                            msg = new String(b,0,len);
                            System.out.println(msg);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

      The client (create multiple clients, the same code):

public class BioClient1 {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        Scanner scanner = new Scanner(System.in);
        socket.connect(new InetSocketAddress("127.0.0.1",9999));
        String className = "这是来自"+Thread.currentThread().getStackTrace()[1].getClassName()+"的消息";
        while(true){
            System.out.println("请输入内容");
            String next = scanner.next();
            socket.getOutputStream().write(className.getBytes());
            socket.getOutputStream().write(next.getBytes());
        }
    }
}

      Tests are as follows:

      

Three .NIO simple analysis

  NIO is non-blocking IO, reason is that the data is ready, the notification by the selector to the server, but before the data is ready, the server without waiting.

  1. Buffer

    BIO In operation, all data is in the form of flow operation, in the NIO, the buffers are used to operate.

    NIO Buffer is the Buffer class, it is an abstract class under java.nio package, you can view the details of the JDK API documentation, such as the following figure

    

    Open Buffer class, can be seen below (with which the method can view JDK documentation)

     

  2. Direct and indirect buffer buffer

    Direct buffer refers to a buffer to establish in physical memory, the method established by allocateDirect (high efficiency, but not safe)

    Indirect buffer refers to a buffer built on the JVM, established by allocate method (low efficiency, but safety)

  3. Pipeline

    NIO the bridge conduit is transmitting data, which is an interface in java.nio package, API documentation which For details refer to the JDK, for example, FIG.

    

  4. Use the file copy are two ways to achieve NIO Case

    Direct way buffer:

    @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方法都是异步的,完成后会主动调用回调函数。

Guess you like

Origin www.cnblogs.com/ywb-articles/p/11108413.html