很多小伙伴对Java NIO的一些概念和编程不是很理解,希望通过本文对Java NIO与传统IO的对比,可以帮助大家更好地理解和掌握Java NIO。
Java NIO 有两种说法,一种是 New IO,另一种是 Non-blocking IO(非阻塞IO)。
这两种说法都没毛病。
从JDK 1.4开始,Java提供了一系列IO新特性,所以称之为New IO。而NIO提供了非阻塞的I/O操作方式,所以又可以称之为 Non-blocking IO。
相对于传统的 Java IO API,NIO API 不论是概念还是编程方式,对于开发人员来讲都没有那么的直观,理解起来比较困难。
(下面通过对比Java的传统IO和NIO编程,让小伙伴们轻松理解并掌握Java NIO。)
在基于传统的Java IO API进行网络编程时,通过3个步骤就可以完成网络通信工作:
整个流程相对直观简单。示例代码如下图
而在Java NIO中,引入了一系列新的概念,比如通道(Channel)、缓冲区(Buffer)、选择器(Selector)等。
先来看一下这些概念:
这些概念给我的感觉就是:好像看了,又好像没看。
对于初学者来说,在概念的转换和学习过程中可能会有一定的难度。所以还是要结合实际的例子来理解。
与上面相同的功能,看看利用Java NIO API是如何编写的。
可以看到,完成网络通信的3个步骤依然存在,但是有几处代码不一样:
SocketChannel
替代了InputStream/OutputStream
,既可以读又可以写。ByteBuffer
替代了byte[]
,两者区别就是,ByteBuffer
多了清除、标记、重置等功能,也是为什么说Java NIO 是面向缓冲区。Selector.open()
、selector.select()
、xx.register(selector)
等。替代不难理解,主要是,这个Selector
是什么?
这个Selector
也就是Java NIO的核心组件,其工作模式就是《BIO、NIO、IO多路复用模型详细介绍&Java NIO 网络编程》说到的IO多路复用。
通过使用Selector
,一个单独的线程可以去处理多个客户端的连接请求、读写操作。具体体现在以下几处:
ServerSocketChannel
到 Selector
,并监听 ACCEPT
事件。这样意味着ServerSocket
不用去accept()
等待客户端的连接,而是交给了Selector
去等待。Selector
,并监听 READ
事件。 意味着,如果Socket数据没有准备好,由Selector
去等待。这样的话,只要是注册到Selector
中的事件,不论多少个客户端的连接或输入输出,都会在selector.select()
(第16行)统一由一个线程去阻塞等待。从而减少整体阻塞的次数,提高性能。
Java NIO 并不是完全非阻塞,只是通过事件驱动机制和缓冲区减少系统调用次数,减少了阻塞等待的时间。理解Java NIO需要重点理解事件驱动机制。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。