【Java面试】说说NIO和IO的区别,再说说Linux支持那些IO模型?

简介: 【Java面试】说说NIO和IO的区别,再说说Linux支持那些IO模型?

IO

IO一般说的就是IO流了,IO流一般是从磁盘或者其他主机上去读取或者写入数据,当然,除了磁盘,还有网络,内存都是可以作为IO流的数据的来源或者目的地。再Java中也提供了字节流或者字符流去实现这种对数据流的操作。那么如果是面向网络的话,Java中也提供了这种对TCP/IP协议的封装的这种接口,叫Socket,通过Socket我们就可以实现数据再网络上的传递。基于Socket的IO通讯,其实它是一种阻塞IO,阻塞IO也就是我们所说的BIO,也就是我们说的IO的概念。而阻塞IO的概念的意思就是,一旦某个连接处于阻塞状态,那么后续的连接都需要等待,直到这个连接完成了对应的工作任务之后,服务器才会去响应处理其他的IO请求。

NIO

再JDK1.4之前,只有IO这一种选择,而为了解决越来越大的并发的问题,再JDK1.4之后推出了NIO(New IO/Non Blocking IO),它是一种新的IO机制,它是非阻塞的,相比于传统IO,非阻塞NIO再效率上做了很大的优化,比如加了一些核心的组件,然后又提供了非阻塞这种特性,所以使用NIO进行网络数据传输的时候,即便当前的这个IO事件并没有完成,服务器端也并不会阻塞当前的连接,后续的连接也可以继续跟进,因此并行处理的连接数量会比BIO多得多。

总而言之,IO和NIO的区别,如果站在网络IO的角度上来看,其实是很形象的,前者是阻塞IO,后者就是非阻塞IO。

Linux上的IO模型

Linux支持的IO有BIO,NIO,AIO,其中AIO是一种异步IO。

按照Unix的模型划分,I/O模型可以分为:阻塞I/O模型、非阻塞I/O模型、I/O复用模型、信号

驱动式I/O模型和异步I/O模型,按照POSIX标准来划分只分为两类:同步I/O和异步I/O。

如何区分呢?首先一个I/O操作其实分成了两个步骤:发起IO请求和实际的IO操作。同步I/O和异步I/O的

区别就在于第二个步骤是否阻塞,如果实际的I/O读写阻塞请求进程,那么就是同步I/O,因此阻塞I/O、

非阻塞I/O、I/O复用、信号驱动I/O都是同步I/O,如果不阻塞,而是操作系统帮你做完I/O操作再将结果

返回给你,那么就是异步I/O。

阻塞I/O和非阻塞I/O的区别在于第一步,发起I/O请求是否会被阻塞,如果阻塞直到完成那么就是传统的

阻塞I/O,如果不阻塞,那么就是非阻塞I/O。

对于阻塞I/O模型 ,在linux中,默认情况下所有的socket都是blocking阻塞的。

对于非阻塞I/O模型,在linux下,可以通过设置socket使其变为non-blocking。当对一个non-blocking

socket执行读操作时,如果没有数据准备好,那么就立刻返回,如果数据准备好了,那么就立刻复制数据报。

对于IO复用模型,可以调用select或者poll,那么系统会阻塞再这两个系统调用的某一个之上,而不是直接阻塞在真正的IO系统调用上。

对于信号驱动式I/O模型,我们可以用信号,让内核在描述符就绪时发送SIGIO信号通知我们,如果数据准备好了,那么内核发送一个SIGIO信号给我们的信号处理程序,那么此时我们的应用进程就知道可以去读取复制数据了。

对于异步I/O模型,用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从内核

的角度,当它受到一个asynchronousread之后,首先它会立刻返回,所以不会对用户进程产生任

何block。然后,内核会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,

内核会给用户进程发送一个signal,告诉它read操作完成了,此时数据已经在内存中了,等待应用进程去读取。

从前面 I/O 模型的分类中,我们可以看出 AIO 的动机。阻塞模型需要在 I/O 操作开始时阻塞应用程序。这意味着不可能同时重叠进行处理和 I/O 操作。

非阻塞模型允许处理和 I/O 操作重叠进行,但是这需要应用程序来检查 I/O 操作的状态。

对于异步I/O ,它允许处理和 I/O 操作重叠进行,包括 I/O 操作完成的通知。除了需要阻塞之外,select 函数所提供的功能(异步阻塞 I/O)与 AIO 类似。不过,它是对通知

事件进行阻塞,而不是对 I/O 调用进行阻塞。

同时Linux还支持多路复用,其中比较经典的就是epoll模型了。


相关文章
|
5月前
|
Java Linux API
IO模型
BIO、NIO、AIO是Java中处理网络I/O的三种模型。BIO为阻塞式,每个连接需单独线程,高并发下性能受限;NIO通过非阻塞与多路复用提升并发能力,少量线程可处理大量请求;AIO进一步实现异步非阻塞,数据复制时线程可释放,由回调机制处理后续操作。三者适用于不同场景,BIO易用但低效,NIO高效但复杂,AIO理论性能更优但目前在Linux上仍依赖多路复用实现。Java 21引入虚拟线程后,BIO也可兼具高性能与易编写特性。
186 2
|
2月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
203 1
|
4月前
|
存储 Ubuntu 安全
Linux中Centos和Ubuntu的区别
CentOS主要面向服务器环境,而Ubuntu适用于服务器和桌面环境。   CentOS提供更精简的安装,而Ubuntu提供更广泛的开箱即用功能。   CentOS遵循RHEL的所有安全实践,而Ubuntu在安全方面采取更积极的方法。
|
4月前
|
Ubuntu 安全 Unix
Linux和Ubuntu有什么区别
综上所述,Linux和Ubuntu之间存在明显的区别。Linux是一种操作系统内核,而Ubuntu是基于Linux内核的发行版本,具有更好的易用性、社区支持和软件仓库。用户可以根据自己的需求选择不同的Linux发行版本,如果需要一个稳定、易于使用的桌面环境,Ubuntu是一个不错的选择。如果需要更加灵活和定制性强的系统,其他Linux发行版本可能更加适合。
|
网络协议 Dubbo Java
一文搞懂NIO、AIO、BIO的核心区别(建议收藏)
本文详细解析了NIO、AIO、BIO的核心区别,NIO的三个核心概念,以及NIO在Java框架中的应用等。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
一文搞懂NIO、AIO、BIO的核心区别(建议收藏)
|
5月前
|
安全 Unix Java
linux中kill -9和kill -15区别
在 Linux/Unix 系统中,`kill -9` 和 `kill -15` 是终止进程的常用命令,核心区别在于发送的信号类型不同,导致进程终止行为截然不同。`kill -15`(SIGTERM)允许进程进行清理操作后优雅退出,适用于正常关闭;而 `kill -9`(SIGKILL)则强制终止进程,不给予任何清理机会,仅在进程无响应时使用。本文从信号类型、行为、工作原理及使用建议等方面进行详细对比,帮助你更安全、有效地管理进程。
690 0
|
9月前
|
Unix Linux 编译器
windows下和linux下cmake的规则有区别吗
通过合理使用CMake的条件逻辑和平台特定的配置选项,开发者可以编写更加灵活和健壮的CMake脚本,确保项目在Windows和Linux上的一致性和可移植性。
468 76
|
10月前
|
Linux
linux syscall和int 80的区别
通过以上内容,希望您能更清晰地理解 `int 0x80` 和 `syscall` 的区别及其在不同系统架构中的应用。
699 99
|
10月前
|
缓存 Ubuntu Linux
Linux中yum、rpm、apt-get、wget的区别,yum、rpm、apt-get常用命令,CentOS、Ubuntu中安装wget
通过本文,我们详细了解了 `yum`、`rpm`、`apt-get`和 `wget`的区别、常用命令以及在CentOS和Ubuntu中安装 `wget`的方法。`yum`和 `apt-get`是高层次的包管理器,分别用于RPM系和Debian系发行版,能够自动解决依赖问题;而 `rpm`是低层次的包管理工具,适合处理单个包;`wget`则是一个功能强大的下载工具,适用于各种下载任务。在实际使用中,根据系统类型和任务需求选择合适的工具,可以大大提高工作效率和系统管理的便利性。
1172 25
|
12月前
|
Linux Android开发 开发者
linux m、mm、mmm函数和make的区别
通过理解和合理使用这些命令,可以更高效地进行项目构建和管理,特别是在复杂的 Android 开发环境中。
636 18

热门文章

最新文章