Java NIO是New IO还是Non-blocking IO

前言

很多小伙伴对Java NIO的一些概念和编程不是很理解,希望通过本文对Java NIO与传统IO的对比,可以帮助大家更好地理解和掌握Java NIO。

NIO到底叫啥

Java NIO 有两种说法 ,一种是 New IO ,另一种是 Non-blocking IO(非阻塞IO)。

这两种说法都没毛病

从JDK 1.4开始,Java提供了一系列IO新特性 ,所以称之为New IO。而NIO提供了非阻塞的I/O操作方式,所以又可以称之为 Non-blocking IO。

通过对比理解NIO

相对于传统的 Java IO API,NIO API 不论是概念还是编程方式,对于开发人员来讲都没有那么的直观,理解起来比较困难。

(下面通过对比Java的传统IO和NIO编程,让小伙伴们轻松理解并掌握Java NIO。)

传统IO网络编程

在基于传统的Java IO API进行网络编程时,通过3个步骤就可以完成网络通信工作:

  1. 接受一个连接请求的Socket对象。
  2. 获取Socket关联的的输入/输出流。
  3. 读取输入流的数据或向输出流写入数据。

整个流程相对直观简单。示例代码如下图

NIO引入的新概念

而在Java NIO中,引入了一系列新的概念,比如通道(Channel )、缓冲区(Buffer )、选择器(Selector)等。

先来看一下这些概念:

  • 通道Channel):通道是连接数据源和缓冲区的桥梁。数据可以通过通道从数据源读取到缓冲区,或者从缓冲区写入到数据源。
  • 缓冲区Buffer):缓冲区是Java NIO中用于存储数据的核心组件。它是一个容器对象,用于存储要写入通道或从通道读取的数据。
  • 选择器Selector):选择器用于非阻塞I/O操作。它可以同时监控多个通道的状态(如是否准备好进行读或写操作),这使得开发者可以编写高效的、非阻塞的I/O代码。

这些概念给我的感觉就是:好像看了,又好像没看

对于初学者来说,在概念的转换和学习过程中可能会有一定的难度。所以还是要结合实际的例子来理解。

与上面相同的功能,看看利用Java NIO API是如何编写的。

NIO网络编程

两者区别

可以看到,完成网络通信的3个步骤依然存在,但是有几处代码不一样:

  1. SocketChannel替代了InputStream/OutputStream,既可以读又可以写。
  2. ByteBuffer替代了byte[],两者区别就是,ByteBuffer多了清除、标记、重置等功能,也是为什么说Java NIO 是面向缓冲区。
  3. 多了陌生的代码,比如,Selector.open()selector.select()xx.register(selector)等。

替代不难理解,主要是,这个Selector是什么?

这个Selector也就是Java NIO的核心组件,其工作模式就是《》说到的IO多路复用。

NIO的事件驱动

通过使用Selector,一个单独的线程可以去处理多个客户端的连接请求、读写操作。具体体现在以下几处:

  1. 第12行,注册 ServerSocketChannelSelector,并监听 ACCEPT 事件。这样意味着ServerSocket不用去accept()等待客户端的连接,而是交给了Selector去等待。
  2. 第33行,注册新连接到 Selector,并监听 READ 事件。 意味着,如果Socket数据没有准备好,由Selector去等待。

这样的话,只要是注册到Selector中的事件,不论多少个客户端的连接或输入输出,都会在selector.select()(第16行)统一由一个线程去阻塞等待。从而减少整体阻塞的次数,提高性能

总结

Java NIO 并不是完全非阻塞,只是通过事件驱动机制和缓冲区减少系统调用次数,减少了阻塞等待的时间。理解Java NIO需要重点理解事件驱动机制。

相关推荐
曹牧4 分钟前
文档格式:OFD
java
豆角焖肉30 分钟前
Maven进阶与搭建私服
java·maven
大不点wow40 分钟前
Java序列化与反序列化:让对象走出JVM
java·开发语言·jvm
止语Lab44 分钟前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活44 分钟前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
噢,我明白了1 小时前
Java中日期和字符串的处理
java·开发语言·日期
程序员天天困1 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn1 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
dkbnull1 小时前
Spring Boot请求处理组件对比详解
java·spring boot
jun_bai1 小时前
Orthanc服务器使用java上传dicom影像文件
java·运维·服务器