关于BIO,NIO,AIO的理解

Posted fan123yh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于BIO,NIO,AIO的理解相关的知识,希望对你有一定的参考价值。

BIO:同步阻塞式IO

NIO:同步非阻塞式IO

AIO(NIO2.0):异步非阻塞式IO

同步:指虚拟机来完成IO读写,如果读写没有完成程序一直等待。

异步:指将读写交给操作系统来做,java代码要干的事就是将想读的写的东西给操作系统然后返回状态值,最后让操作系统通知程序是否完成。

阻塞:指对网络通信,一个客户端对应一个服务器线程,当链接数量多的时候,就会发生阻塞,其余的客户端连不上服务器。

非阻塞:将所谓的一个链接对应一个线程转化为一个请求对应一个线程,这里引入了通道和多路复用技术,由多路复用器来轮询通道是否请求读写,然后创建一个线程来处理他。

 

异步一般与操作系统关系比较密切,不同的操作系统异步的效率也是不一样的。

阻塞是可以用代码方式体现的:

1.创建服务器类,创建私有多路复用器,和buffer缓冲区对象。

2.创建服务器类的构造方法,通道绑定地址并且绑定通道设置监听。

3.创建客户端类,绑定通道,并用buffer输入通道。

技术图片
  1 package com.fan;
  2 
  3 import java.io.IOException;
  4 import java.net.InetSocketAddress;
  5 import java.nio.ByteBuffer;
  6 import java.nio.channels.SelectionKey;
  7 import java.nio.channels.Selector;
  8 import java.nio.channels.ServerSocketChannel;
  9 import java.nio.channels.SocketChannel;
 10 import java.util.Iterator;
 11 
 12 public class Server implements Runnable 
 13 
 14     private Selector selector;//创建多路复用器。
 15 
 16     private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);//创建ByteBuffer,并分配长度。
 17 
 18     public Server(int port) //创建构造函数。
 19         try 
 20 
 21             this.selector = Selector.open();//打开多路复用器。
 22 
 23             ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();//打开服务器通道channel。
 24 
 25             serverSocketChannel.configureBlocking(false);//设置该多通道为非阻塞的。
 26 
 27             serverSocketChannel.bind(new InetSocketAddress(port));//给通道绑定服务器地址。
 28 
 29             serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);//通道注册到多路复用器中,并设置监听事件。
 30 
 31             System.out.println("Server start, port :" + port);
 32 
 33          catch (Exception e) 
 34 
 35         
 36     
 37 
 38     @Override
 39     public void run() 
 40         while (true) 
 41             try 
 42                 this.selector.select();//让多路复用器进行监听。
 43 
 44                 Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();//返回多路选择器已经选择的集。
 45 
 46                 while (iterator.hasNext()) //进行遍历。
 47 
 48                     SelectionKey selectionKey = iterator.next();//获取一个选择的元素。
 49 
 50                     iterator.remove();//将容器移除。
 51 
 52                     if (selectionKey.isValid()) 
 53                         if (selectionKey.isAcceptable()) 
 54                             this.accept(selectionKey);
 55                         
 56                         if (selectionKey.isReadable()) 
 57                             this.read(selectionKey);
 58                         
 59                         if (selectionKey.isWritable()) 
 60                             //this.write(selectionKey); //ssc
 61                         
 62                     
 63                 
 64 
 65              catch (Exception e) 
 66 
 67             
 68         
 69     
 70 
 71     private void write(SelectionKey key) 
 72         //ServerSocketChannel ssc =  (ServerSocketChannel) key.channel();
 73         //ssc.register(this.seletor, SelectionKey.OP_WRITE);
 74     
 75 
 76     private void read(SelectionKey key) 
 77         try 
 78             this.byteBuffer.clear();//清空缓冲区旧的数据
 79 
 80             SocketChannel socketChannel = (SocketChannel) key.channel();//获取之前注册的socket通道对象
 81 
 82             int read = socketChannel.read(this.byteBuffer);//将通道数据读到buffer中
 83 
 84             if(read==-1)//如果没数据就返回
 85                 key.channel().close();
 86                 key.cancel();
 87                 return;
 88             
 89 
 90             this.byteBuffer.flip();//有数据则进行读取 读取之前需要进行复位方法(把position 和limit进行复位)
 91 
 92             byte[] bytes = new byte[this.byteBuffer.remaining()];//根据缓冲区的数据长度创建相应大小的byte数组,接收缓冲区的数据
 93 
 94             this.byteBuffer.get(bytes);// 接收缓冲区数据
 95 
 96             String body = new String(bytes).trim();
 97 
 98             System.out.println("Server : " + body);
 99 
100         catch (Exception e)
101 
102         
103     
104     private void accept(SelectionKey key) 
105 
106         try 
107             ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
108             SocketChannel accept = serverSocketChannel.accept();
109             accept.configureBlocking(false);
110             accept.register(this.selector, SelectionKey.OP_READ);
111         catch (Exception e)
112 
113         
114     
115 
116     public static void main(String[] args) 
117 
118         new Thread(new Server(8765)).start();
119 
120     
121 
122 
View Code
技术图片
 1 package com.fan;
 2 
 3 import java.io.IOException;
 4 import java.net.InetSocketAddress;
 5 import java.nio.ByteBuffer;
 6 import java.nio.channels.SocketChannel;
 7 
 8 public class Client 
 9 
10 
11     public static void main(String[] args) 
12         InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8765);
13 
14         SocketChannel sc = null;
15 
16         ByteBuffer buf = ByteBuffer.allocate(1024);
17 
18         try 
19 
20             sc = SocketChannel.open();
21 
22             sc.connect(address);
23 
24             while (true) 
25 
26                 byte[] bytes = new byte[1024];
27 
28                 System.in.read(bytes);
29 
30                 buf.put(bytes);
31 
32                 buf.flip();
33 
34                 sc.write(buf);
35 
36                 buf.clear();
37 
38             
39 
40          catch (IOException e) 
41 
42             e.printStackTrace();
43 
44          finally 
45 
46             if (sc != null) 
47 
48                 try 
49 
50                     sc.close();
51 
52                  catch (IOException e) 
53 
54                     e.printStackTrace();
55 
56                 
57 
58             
59 
60         
61 
62     
63 
64 
View Code

 

以上是关于关于BIO,NIO,AIO的理解的主要内容,如果未能解决你的问题,请参考以下文章

JAVA 中BIO,NIO,AIO的理解

初理解Java中的BIO,NIO,AIO

BIO NIO AIO

一站式学习Java网络编程 全面理解BIO/NIO/AIO完整版

JAVA 中BIO,NIO,AIO的理解

Java中BIO,NIO,AIO的理解