Java 入门指南:初识 Java NIO

NIO 的引入

在传统的 Java I/O 模型(BIO)中,I/O 操作是以阻塞的方式进行的。当一个线程执行一个 I/O 操作时,它会被阻塞直到操作完成。这种阻塞模型在处理多个并发连接时可能会导致性能瓶颈,因为需要为每个连接创建一个线程,而线程的创建和切换都是有开销的。

为了解决这个问题,在 Java1.4 版本引入了 NIO(New I/O or Non-Blocking I/O)java.nio。提供了一种基于缓冲区、选择器和非阻塞 IO 模型的 IO 处理方式。相比于之前的 BIO 模型,NIO 可以实现更高的并发、更低的延迟以及更少的资源消耗。

I/O 包和 NIO 已经很好地集成了,java.io 也已经以 NIO 为基础重新实现了,所以现在它可以利用 NIO 的一些特性。例如,java.io 包中的一些类包含以块的形式读写数据的方法,这使得即使在面向流的系统中,处理速度也会更快。

使用 NIO 并不一定意味着高性能,它的性能优势主要体现在高并发和高延迟的网络环境下。当连接数较少、并发程度较低或者网络传输速度较快时,NIO 的性能并不一定优于传统的 BIO 。

NIO 的组成部分

缓冲区(Buffer)
  • 定义:缓冲区是 Java NIO 中的一个核心概念,它是用于存储IO操作数据的一段连续区域。
  • 类型 :Java NIO 提供了多种类型的缓冲区,如 ByteBufferCharBufferIntBuffer 等,以适应不同的数据类型需求。
  • 属性:每个缓冲区都有四个重要的属性,分别是容量(Capacity)、位置(Position)、限制(Limit)和标记(Mark)。
  • 操作:缓冲区的读写操作会修改其位置和限制属性,以确保数据能够正确地进行传输和处理。
通道(Channel)
  • 定义:通道是 Java NIO 中网络通信和文件 IO 操作的抽象,类似于传统 IO 中的 Stream,但它更加灵活和高效。
  • 类型 :Java NIO 提供了多种类型的通道,如 FileChannel(用于文件读写操作)、DatagramChannel(用于 UDP 协议的网络通信)、SocketChannel(用于 TCP 协议的网络通信)和 ServerSocketChannel(用于监听 TCP 连接请求)。
  • 特点:通道可以与缓冲区结合使用,通过缓冲区直接在内存中进行数据的读写操作,从而避免了传统IO中的频繁磁盘访问。
选择器(Selector)
  • 定义:选择器是Java NIO中的一个重要组件,它允许一个线程同时监听多个通道上的IO事件。
  • 作用:通过选择器,可以实现单线程管理多个通道的方式,从而大大提高IO操作的并发性能。
  • 使用:在选择器的模型中,每个通道都会注册到一个选择器上,并且每个通道都有一个其唯一的选择键(SelectionKey)对象来代表这个通道。当通道上的IO事件发生时,选择器会通知相应的线程进行处理。

NIO 与 BIO 的差异

I/O 与 NIO 最重要的区别是数据打包和传输 的方式,I/O 以流的方式处理数据,而 NIO 以块(缓冲区)的方式处理数据

面向流的 I/O 一次处理一个字节数据: 一个输入流产生一个字节数据,一个输出流消费一个字节数据。为流式数据创建过滤器非常容易,链接几个过滤器,以便每个过滤器只负责复杂处理机制的一部分。不利的一面是,面向流的 I/O 通常相当慢。

面向块的 I/O 一次处理一个数据块,按块处理数据比按流处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。

传统 I/O 使用 Socket 和 SeverSocket 进行网络传输,存在阻塞问题。NIO 提供了 ServerChannelServerSocketChannel,支持非阻塞网络传输,提高了并发处理能力。

BIO、NIO 与 AIO

BIO(Blocking I/O):采用阻塞式 I/O 模型,线程在执行 I/O 操作时被阻塞,无法处理其他任务,适用于连接数较少且稳定的场景。

NIO(New I/O 或 Non-blocking I/O):使用非阻塞 I/O 模型,线程在等待 I/O 时可执行其他任务,通过 Selector 监控多个 Channel 上的事件,提高性能和可伸缩性,适用于高并发场景。

AIO(Asynchronous I/O):采用异步 I/O 模型,线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程,进一步提高了并发处理能力,适用于高吞吐量场景。

NIO 的优势

IO 操作主要在 文件IO网络IO 场景下应用。NIO 的优势之处主要体现在网络 IO 场景下。

NIO(New I/O)的设计目标是解决传统 I/O(BIO,Blocking I/O)在处理大量并发连接时的性能瓶颈。传统 I/O 在网络通信中主要使用阻塞式 I/O,为每个连接分配一个线程。当连接数量增加时,系统性能将受到严重影响,线程资源成为关键瓶颈。而 NIO 可以在单个线程中处理多个并发连接 ,从而在网络传输中显著提高性能

  1. NIO 支持非阻塞 I/O,这意味着在执行 I/O 操作时,线程不会被阻塞。这使得在网络传输中可以有效地管理大量并发连接(数千甚至数百万)。而在操作文件时,这个优势没有那么明显,因为文件读写通常不涉及大量并发操作。

  2. NIO 支持 I/O 多路复用 ,这意味着一个线程可以同时监视多个通道(如 Socket),并在 I/O 事件(如可读、可写)准备好时处理它们。这大大提高了网络传输中的性能,因为单个线程可以高效地管理多个并发连接。操作文件时这个优势也无法提现出来。

  3. NIO 提供了 ByteBuffer,可以高效地管理缓冲区。这在网络传输中很重要,因为数据通常是以字节流的形式传输。操作文件的时候,虽然也有缓冲区,但优势仍然不够明显。

相关推荐
bobz9657 分钟前
tcp/ip 中的多路复用
后端
bobz96517 分钟前
tls ingress 简单记录
后端
皮皮林5511 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友1 小时前
什么是OpenSSL
后端·安全·程序员
bobz9652 小时前
mcp 直接操作浏览器
后端
前端小张同学4 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook4 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康5 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在5 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net
文心快码BaiduComate5 小时前
文心快码入选2025服贸会“数智影响力”先锋案例
前端·后端·程序员