Java BIO与NIO比较

来源:互联网 发布:java调用url接口 编辑:程序博客网 时间:2024/06/04 01:13

参考:http://blog.csdn.net/skiof007/article/details/52873421
http://blog.csdn.net/z173273946/article/details/50010375

这里写图片描述
BIO与NIO对比
这里写图片描述
NIO内部机制简单模拟

1、BIO实现
针对客户端的每个请求,服务器都是新建一个线程去专门处理,高并发情况下,服务器需要开辟很多线程,操作系统可以开辟线程数也是有限制的。另一方面线程内处理的过程是阻塞的,即客户端和服务器线程都有相互等待的代价

2、NIO实现
客户端和服务器都维护一个选择器Selector,服务器在其Selector上注册来自客户端的连接事件,并启用一个线程轮询其Selector,当有客户端试图与服务器建立连接时,会被Selector捕获到,然后服务器会为这个客户端分配一个SocketChannel,并在其Selector上注册读/写事件。同样,如果客户端尝试进行读/写操作,也会给Selector捕获到,以此类推。

3、NIO与BIO区别

是否缓存数据:BIO直接从流中读写数据,并不会像NIO那样先把数据存储到Buffer中,再后续处理
服务器需要线程数量:NIO模式下理论上服务器只需要一个线程就可以监听不同客户端的IO事件

4、使用BIO和NIO读取数据的差异

有一块数据如下:
name:liup
sex:male

首先使用BIO读取
InputStream input = … ; // get the InputStream from the client socket
//使用inputStreamReader将字节流转换为字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String strLine = reader.readLine();
注意这里readLine是阻塞型读取,当该方法返回时即代表数据已读取完毕,可以处理数据了

然后使用NIO读取
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(48);
int bytesRead = channel.read(buffer);
注意:此时只知道有部分数据被读到缓冲区中,数据是否已经被读取完(准备就绪)是不知道的,需要额外自己写代码判断

5、Java对BIO、NIO、AIO的支持
Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善
Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,

原创粉丝点击