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


相关文章
|
6月前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
180 4
|
6月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
264 1
|
8月前
|
缓存 前端开发 Java
Java类加载机制与双亲委派模型
本文深入解析Java类加载机制,涵盖类加载过程、类加载器、双亲委派模型、自定义类加载器及实战应用,帮助开发者理解JVM核心原理与实际运用。
|
8月前
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
8月前
|
SQL Java 数据库连接
Java IO流(一):字节流与字符流基础
本文全面解析Java IO流,涵盖字节流、字符流及其使用场景,帮助开发者理解IO流分类与用途,掌握文件读写、编码转换、异常处理等核心技术,通过实战案例提升IO编程能力。
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
Java 大视界 -- Java 大数据机器学习模型在自然语言生成中的可控性研究与应用(229)
本文深入探讨Java大数据与机器学习在自然语言生成(NLG)中的可控性研究,分析当前生成模型面临的“失控”挑战,如数据噪声、标注偏差及黑盒模型信任问题,提出Java技术在数据清洗、异构框架融合与生态工具链中的关键作用。通过条件注入、强化学习与模型融合等策略,实现文本生成的精准控制,并结合网易新闻与蚂蚁集团的实战案例,展示Java在提升生成效率与合规性方面的卓越能力,为金融、法律等强监管领域提供技术参考。
|
8月前
|
机器学习/深度学习 算法 Java
Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用(223)
本文探讨了Java大数据与机器学习模型在生物信息学中基因功能预测的优化与应用。通过高效的数据处理能力和智能算法,提升基因功能预测的准确性与效率,助力医学与农业发展。
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!

热门文章

最新文章