当前位置 : 主页 > 编程语言 > java >

Java IO模型(BIO | NIO | AIO)

来源:互联网 收集:自由互联 发布时间:2023-09-06
Java IO 模型之 BIO,NIO,AIO (qq.com) Java 中 BIO、NIO、AIO 的区别? 常见的5种IO模型 UNIX 系统下, IO 模型一共有 5 种:同步阻塞 I/O、同步非阻塞 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O。

Java IO 模型之 BIO,NIO,AIO (qq.com)

Java 中 BIO、NIO、AIO 的区别?

常见的5种IO模型

UNIX 系统下, IO 模型一共有 5 种:同步阻塞 I/O、同步非阻塞 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O。

下面我们说说Java中3种常见IO模型

BIO(Blocking I/O)

BIO属于同步阻塞IO模型

同步阻塞IO模型中,应用程序发起read调用后,会一直阻塞,直到内核把数据拷贝到用户空间。

图源:《深入拆解Tomcat & Jetty》

在客户端连接数量不高的情况下是没问题的。但当面对十万甚至百万级连接的时候,传统的BIO模型是无能为力的。

NIO(Non-blocking/New I/O)

NIO 有三大核心组件:Channel(通道), Buffer(缓冲区),Selector(多路复用器)

  • Selector:Selector允许单线程处理多个Channel。如果应用打开了多个连接(通道Channel),但是每个连接的流量都很低,使用Selector就会很方便。要使用Selector,得向Selector注册Channel,然后调用他的select方法,这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件。
  • Channel:基本上所有的IO在NIO都从一个Channel开始,Channel有点像流,数据可以从Channel读到Buffer,也可以从Buffer写到Channel。
  • Buffer:缓冲区本质上是一个可以读写数据的内存块,可以理解是一个容器对象(含数据),该对象提供了一组方法,可以更轻松地使用内存块。缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况,Channel提供从文件,网络读取数据的渠道,但是读取或者写入的数据都必须经由Buffer。

应用场景:NIO的方式适用于连接数目多且连接比较短的架构,比如聊天服务器,弹幕系统,服务器间通讯。NIO的编程比较复杂。

NIO底层在JDK1.4版本使用linux的内核函数select()或poll()来实现,Selector每次都会轮询所有的SockChannel看下哪个Channel有读写事件,有的话就处理,没有就继续遍历,JDK1.5开始引入了epoll基于事件的响应机制来优化NIO。

图片

Selector类似一个观察者,只要我们把需要探知的SockChannel告诉Selector,我们接着做别的事情,当有事情发生时,他会通知我们,传回一组SelectionKey(Linux内核中的rdlist就绪事件列表),我们读取这些Key,就会获得我们刚刚注册过的SocketChannel。然后,我们从这个Channel中读取并处理这些数据,Selector内部原理实际是在做一个对所注册的Channel(SocketChannel)不断地轮询访问,一旦轮到一个Channel有所注册的事件发生,比如数据来了,他就会站起来报告,交出一把Key,通过Key读取这个Channel的内容。

图片

AIO(Asynchronous I/O,NIO 2.0)

AIO 也就是 NIO 2。Java 1.7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型。

AIO模型主要基于事件和回调机制。当一个I/O操作完成时,操作系统会通知应用程序,然后应用程序执行相应的回调函数进行处理。在AIO模型中,只需要少量的线程就可以处理大量的连接,大大提高了系统的并发处理能力。

一般适用于连接数较多且连接时间较长(重操作)的应用。

然而,AIO模型的兼容性相对较差,需要操作系统支持,且不同的操作系统对AIO的实现方式也有所不同。

图片

BIO、 NIO、 AIO 对比

图片

为什么Netty使用 NIO 而不是 AIO ?

在 Linux 系统上,AIO 的底层实现仍使用 Epoll,没有很好实现 AIO,因此在性能上没有明显的优势。

Netty 是异步非阻塞框架,Netty 在 NIO 上做了很多异步的封装。

上一篇:谈谈你对面向对象的理解
下一篇:没有了
网友评论