NIO,New IO,相对Java1.4之前老的IO(OIO)。
操作系统就说Linux吧。
Linux上的I/O模型大致分为五种:
阻塞式,非阻塞式,I/O复用,信号驱动式I/O,异步I/O(AIO)。
(菜鸟我本来以为I/O复用已经算很高级的了,还经常用这个来考别人,如果对方答不上来还要沾沾自喜一番。羞愧地无地自容了,掩面。)
言归正传,这里说的I/O都是针对网络的,文件以及其他外设暂时不考虑。
有必要先解释一下阻塞、非阻塞,同步、异步的概念。
阻塞和非阻塞指的是执行一个操作是等操作结束再返回,还是马上返回。比如你去车站接朋友,这是一个操作。可以有两种执行方式。第一种,你这人特实诚,老早就到了车站一直等到车来了接到朋友为止。第二种,你到了车站,问值班的那趟车来了没有,“还没有”,你出去逛一圈,可能过会回来再问。第一种就是阻塞方式,第二种则是非阻塞的。
我认为阻塞和非阻塞讲得是做事方法,是针对做事的人而言的。
同步和异步又是另外一个概念,它是事件本身的一个属性。比如老板让你去搬一堆石头,而且只让你一个人干,你只好自己上阵,最后的结果是搬完了,还是你砸到脚了,只有搬完了才知道。这就是同步的事件。如果老板还给你个小弟,你就可以让小弟去搬,搬完了告你一声。这就变成异步的了。其实异步还可以分为两种:带通知的和不带通知的。前面说的那种属于带通知的。有些小弟干活可能主动性不是很够,不会主动通知你,你就需要时不时的去关注一下状态。这种就是不带通知的异步。
对于同步的事件,你只能以阻塞的方式去做。
而对于异步的事件,阻塞和非阻塞都是可以的。非阻塞又有两种方式:主动查询和被动接收消息。被动不意味着一定不好,在这里它恰恰是效率更高的,因为在主动查询里绝大部分的查询是在做无用功。对于带通知的异步事件,两者皆可。而对于不带通知的,则只能用主动查询。
回到I/O,不管是I还是O,对外设的访问都可以分成请求和执行两个阶段。请求就是看外设的状态信息(比如是否准备好了),执行才是真正的I/O操作。在Linux 2.6之前,只有“请求”是异步事件,2.6之后才引入AIO把“执行”异步化。别看Linux/Unix是用来做服务器的,这点上比Windows落后了好多,IOCP(Windows上的AIO)在Win2000上就有了。这也是为什么ACE框架中,Proactor模型在Linux上只能是模拟的。
Linux上的前四种I/O模型的“执行”阶段都是同步的,只有最后一种才做到了真正的全异步。
第一种阻塞式是最原始的方法,也是最累的办法。当然累与不累要看针对谁。应用程序是和内核打交道的。对应用程序来说,这种方式是最累的,但对内核来说这种方式恰恰是最省事的。还拿接人这事为例,你就是应用程序,值班员就是内核,如果你去了一直等着,值班员就省事了。
当然现在计算机的设计,包括操作系统,越来越为终端用户考虑了,为了让用户满意,内核慢慢的承担起越来越多的工作。IO模型的演化也是如此。
非阻塞式,I/O复用,信号驱动式I/O其实都是非阻塞的,当然是针对“请求”这个阶段。非阻塞式是主动查询外设状态。I/O复用里的select,poll也是主动查询,不同的是select和poll可以同时查询多个fd(文件句柄)的状态,另外select有fd个数的限制。epoll是基于回调函数的。信号驱动式I/O则是基于信号消息的。这两个应该可以归到“被动接收消息”那一类中。
最后就是伟大的AIO的出现,内核把什么事都干了,对上层应用实现了全异步,性能最好,当然复杂度也最高。
才发现,忘了说Java的NIO了。
Java1.4引入的NIO 1.0是基于I/O复用的。在各个平台上会选择不同的复用方式。Linux用的epoll,BSD上用kqueue,Windows上应该是重叠I/O(肯定不是IOCP)。
NIO 2.0里终于有AIO了,Linux上用AIO,Windows上用IOCP。
分享到:
相关推荐
而对于高并发、需要充分利用系统资源的场景,非阻塞I/O和Java NIO提供了更优的解决方案。 了解并熟练掌握这两种I/O模型,有助于开发者编写出高效、可扩展的Java应用程序,特别是在网络编程和服务器开发中,非阻塞I/...
Java 新I/O,也称为NIO(New Input/Output),是Java平台中对传统I/O模型的一种改进。在Java 1.4版本中引入的NIO库为开发人员提供了更高效、非阻塞的数据处理方式,特别适用于高并发、低延迟的系统。NIO的核心在于...
Java NIO(非阻塞I/O)是一种在Java中处理I/O操作的新方式,相比于传统的BIO(阻塞I/O),NIO具有更高的并发性能,尤其适用于需要处理大量并发连接的服务器应用。以下是对NIO核心概念的详细解释: 1. **通道...
Java作为一门广泛使用的开发语言,提供了多种I/O(Input/Output)通信模型,包括传统的阻塞I/O(BIO)、非阻塞I/O(NIO)以及异步I/O(AIO)。这些通信模型在不同的场景下有着各自的优势,理解和掌握它们对于优化...
标题“NIO与I/O的区别”涉及到的是Java编程中关于输入/输出(I/O)模型与新I/O(New I/O,NIO)模型的对比。这两种模型在处理数据流时有不同的特性和适用场景,理解它们的区别对于优化Java程序的性能至关重要。 I/O...
非阻塞I/O和异步I/O在某些场景下可能会增加CPU开销。 - **编程复杂度**:异步I/O通常需要更复杂的编程模型,如回调函数或Future/Await,而阻塞I/O则相对简单。 - **兼容性和稳定性**:传统I/O模型在旧版本的Java中已...
Java 1.4引入了NIO(New I/O)框架,提供了一种更有效率的I/O模型,特别是在多路复用I/O(Selector)方面。NIO允许单线程处理多个通道,提高了服务器端并发性能。 8. **文件操作** Java的File类提供了对文件和...
相反,异步I/O模型允许线程在发起I/O请求后立即返回,继续执行其他工作,而操作系统会在后台处理I/O操作,并在完成后通过回调函数或者事件通知线程结果。 在Linux系统中,异步I/O可以通过AIO(Asynchronous Input/...
传统的Java I/O库是基于流的,而Java NIO是基于块的I/O,它提供了更接近操作系统的I/O性能。NIO库的引入主要是为了解决原有I/O库在处理大量数据时效率低下的问题,特别是在网络编程和文件操作方面。 Java NIO中的...
- **JDK1.0-1.3**: 在此期间,Java的I/O模型主要依赖于传统的阻塞I/O方式,这种模式下,应用程序在等待I/O操作完成时无法执行其他任务,导致效率低下。此外,当时的Java在字符集编码支持、文本处理等方面也有诸多...
综上所述,Java NIO与传统阻塞式I/O的主要区别在于NIO支持非阻塞的I/O操作,能够显著提升网络应用程序的并发处理能力和整体性能。尽管NIO的学习曲线较陡峭,且编程模型更为复杂,但对于需要处理大量并发连接的高性能...
首先,Java IO(Input/Output)系统是Java早期版本中的I/O模型,它提供了一系列类和接口,用于处理输入、输出流。Java IO的核心概念是流,流可以分为字节流和字符流,进一步分为输入流和输出流。字节流处理单个字节...
《Java NIO》这本书主要探讨的是Java的非阻塞I/O模型,它是Java标准库提供的一种高效、低延迟的I/O处理方式。NIO代表Non-blocking Input/Output,与传统的I/O模型(BIO,Blocking I/O)相比,NIO在处理大量并发连接...
为了更直观地理解NIO的优势,下面通过一个具体的例子来比较使用传统I/O和NIO读取文件的差异。 ```java // 使用传统I/O读取文件 public void ioRead(String file) throws IOException { FileInputStream in = new ...
- Java NIO还提供了异步I/O操作,通过AsynchronousFileChannel和AsynchronousSocketChannel等类实现,允许程序在等待I/O操作完成时执行其他任务。 7. **文件锁(File Locks)** - NIO提供了文件锁功能,可以在...