【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模型了。


相关实践学习
CentOS 8迁移Anolis OS 8
Anolis OS 8在做出差异性开发同时,在生态上和依赖管理上保持跟CentOS 8.x兼容,本文为您介绍如何通过AOMS迁移工具实现CentOS 8.x到Anolis OS 8的迁移。
相关文章
|
1月前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
95 23
|
15天前
|
Java 编译器 程序员
java中重载和多态的区别
本文详细解析了面向对象编程中多态与重载的概念及其关系。多态是OOP的核心,分为编译时多态(静态多态)和运行时多态(动态多态)。编译时多态主要通过方法重载和运算符重载实现,如Java中的同名方法因参数不同而区分;运行时多态则依赖继承和方法重写,通过父类引用调用子类方法实现。重载是多态的一种形式,专注于方法签名的多样性,提升代码可读性。两者结合增强了程序灵活性与扩展性,帮助开发者更好地实现代码复用。
38 0
|
4月前
|
Ubuntu Linux Shell
(已解决)Linux环境—bash: wget: command not found; Docker pull报错Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled
(已成功解决)Linux环境报错—bash: wget: command not found;常见Linux发行版本,Linux中yum、rpm、apt-get、wget的区别;Docker pull报错Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled
1612 68
(已解决)Linux环境—bash: wget: command not found; Docker pull报错Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled
|
2月前
|
存储 网络协议 Linux
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
124 34
|
3月前
|
Java 程序员 调度
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
149 9
|
3月前
|
安全 Java 程序员
Java面试必问!run() 和 start() 方法到底有啥区别?
在多线程编程中,run和 start方法常常让开发者感到困惑。为什么调用 start 才能启动线程,而直接调用 run只是普通方法调用?这篇文章将通过一个简单的例子,详细解析这两者的区别,帮助你在面试中脱颖而出,理解多线程背后的机制和原理。
118 12
|
2月前
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
|
4月前
|
Linux API C语言
Linux基础IO
Linux基础IO操作是系统管理和开发的基本技能。通过掌握文件描述符、重定向与管道、性能分析工具、文件系统操作以及网络IO命令等内容,可以更高效地进行系统操作和脚本编写。希望本文提供的知识和示例能帮助读者更深入地理解和运用Linux IO操作。
102 14
|
8月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
5月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!

热门文章

最新文章

下一篇
oss创建bucket