BIO、NIO和 AIO总结和对比

Java 中的 BIO、NIO和 AIO 可以理解为是 Java 语言对操作系统的各种 IO 模型的封装。

UNIX网络编程模型

操作系统中最典型的要数UNIX系统的网络编程模型了,UNIX提供了五种I/O模型,分别如下:

阻塞I/O模型:

最基础、也最常用的I/O就是阻塞I/O模型了,在通常情况下,对文件的操作都是阻塞的。在UNIX套接字编程中,在进程空间中调用recvfrom函数(经socket接收数据),只有数据包到达且被复制到应用进程的缓存区中或者发生错误时才返回,在此期间程序将一直等待,进程在它调用recvfrom开始到它返回的时间内都是被阻塞的,所以被称为阻塞I/O模型。

在这里插入图片描述

非阻塞I/O模型:

非阻塞I/O模型主要是将阻塞I/O模型中的“等待数据”进化成了“轮询”。 当recvfrom从应用层到内核的时候,如果该缓冲区没有数据的话,就直接返回一个EWOULDBLOCK错误,一般都对非阻塞I/O模型进行轮询检查这个状态,看内核是不是有数据到来。

在这里插入图片描述

I/O复用模型:

Linux提供select/poll,进程通过将一个或多个fd传递给select或poll系统调用,阻塞在select操作上,这样select/poll可以帮我们侦测多个fd是否处于就绪状态。select/poll是顺序扫描fd是否就绪,而且支持的fd数量有限,因此它的使用受到了一些制约。Linux还提供一个epoll系统调用,epoll使用基于事件驱动方式代替顺序扫描,因此性能更高。当有fd就绪时,立即回调函数rollback。

在这里插入图片描述

信号驱动I/O模型:

首先开启套接口信号驱动I/O功能,并通过系统调用sigaction执行一个信号处理函数(此系统调用立即返回,进程继续工作,它是非阻塞的)。当数据准备就绪时,就为该进程生成一个SIGIO信号,通过信号回调通知应用程序调用recvfrom来读取数据,并通知主循环函数处理数据。

在这里插入图片描述

异步I/O模型:

告知内核启动某个操作,并让内核在整个操作完成后(包括将数据从内核复制到用户自己的缓冲区)通知我们。这种模型与信号驱动模型的主要区别是:信号驱动I/O由内核通知我们何时可以开始一个I/O 操作;异步I/O模型由内核通知我们I/O操作何时已经完成。

在这里插入图片描述

Java中的I/O模型及对比

Java从JDK 1.0版本开始就提供了同步阻塞I/O的支持,在进行网络编程时,只能一个客户端对应一个I/O线程,可靠性非常差,吞吐量很低。

我们也可以利用多线程和线程池来构建伪异步的阻塞I/O,伪异步I/O虽然可以同时支持多客户端和多I/O线程,并且客户端数可以大于I/O线程,但I/O操作本质上还是同步、阻塞I/O,可靠性也不高,吞吐量也不高。

从JDK 1.4开始提供NIO支持,即支持了非阻塞、同步的I/O操作,可以一个I/O线程同时为多个客户端服务,通过NIO构建的程序,吞吐量和可靠性都比较高,但是直接使用JDK的API比较复杂。

异步、非阻塞I/O(AIO)需要操作系统的支持,在linux内核2.6版本中加入了对真正异步IO的支持,Java也从jdk1.7开始支持AIO。这样就不需要一个额外的I/O线程来为客户端连接服务,直接通过被动回调来实现。但同样的使用JDK原生API比较复杂,调试比较困难。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值