浅谈Java NIO

Java NIO(New Input/Output)是Java平台上一种全新的IO API,相较于传统的Java I/O(也称为BIO,阻塞I/O),NIO引入了非阻塞I/O和通道(Channel)的概念,以及缓冲区(Buffer)和选择器(Selector)机制,大大提升了系统的并发处理能力和性能。以下是对NIO实现原理的关键点概述:

  1. 非阻塞I/O

    • 在传统的BIO中,当调用read或write方法时,线程会一直阻塞,直到数据准备好或写出成功。而在NIO中,当调用read或write方法时,如果没有数据可读或不能立即写入,线程不会被阻塞,而是继续执行其他任务,稍后再回来看看数据是否准备就绪。
  2. 通道(Channel)

    • Channel是NIO的基础,它是连接到实体(如硬件设备、文件、网络套接字等)的抽象接口,可以用于读写数据。与传统的InputStream和OutputStream不同,通道既可以读数据也可以写数据。
  3. 缓冲区(Buffer)

    • 缓冲区是NIO中用来存储数据的区域,它是内存的一部分,可以存放不同类型的数据(如字节、字符、整数、浮点数等)。缓冲区有自己的容量、当前位置和界限,这使得NIO能够在批量处理数据时更加高效。
    • Buffer本质上是一块可以写入数据,然后可以从中读取数据的内存。
    • Buffer对象包含三个重要的属性,分别是capacity、position、limit,其中position和limit的含义取决于Buffer处在读模式还是写模式。
      -- capacity:capacity是指Buffer对象的最大容量,即它可以存储的数据总量。一旦创建了一个Buffer对象并分配了容量,这个容量就不能改变。例如,如果你创建了一个容量为100的ByteBuffer,那么它最多可以存储100个字节的数据。
      -- position:position是当前读写操作的当前位置。初始情况下,position设置为0。当你从Buffer中读取数据时,position会向前移动,表示已经读取了多少数据;当你往Buffer中写入数据时,position也会向前移动,表示已经写入了多少数据。position的值始终在0到limit-1之间。
      -- limit:limit标记了Buffer中可以被读取或写入数据的数量边界。对于写入操作,limit等于Buffer的capacity;而对于读取操作,limit等于最后一次写入操作后的position值。也就是说,limit表示的是当前剩余可以读取的数据量或者是还能写入的最大数据量。
      -- 三个属性之间的关系,如下图所示:
  4. 选择器(Selector)

    • 选择器是NIO的重要特性,它允许单个线程监控多个通道的事件(如连接打开、数据到达等)。通过注册通道到选择器,线程可以检测哪些通道准备好了读、写或有新的连接。当调用select方法时,线程会阻塞,直到至少有一个通道准备好进行所关心的操作。
      这是在一个单线程中使用一个Selector处理3个Channel的图示:
  5. 事件驱动

    • NIO基于事件驱动模型,这意味着系统不会浪费CPU周期去持续查询是否有事件发生。相反,当有事件发生时,操作系统会通知Java应用程序,这样可以极大地提高并发处理能力,特别是在大规模并发连接场景下。
  6. 堆外内存(Direct Buffers)

    • NIO还可以直接操作堆外内存,即通过DirectByteBuffer等类直接与操作系统交互,减少Java堆和内核空间之间的数据复制,进一步提高性能。

Java NIO通过非阻塞I/O、通道、缓冲区和选择器机制,实现了高效的数据传输和处理,特别适合处理高并发、低延迟的网络通信和服务端编程场景。

相关推荐
全栈Blue几秒前
详解代理模式-【静态代理与JDK动态代理】(非常的斯国一)
java·代理模式
wangyue48 分钟前
MYSQL 乐观锁
数据库·mysql
踩着阴暗的自己向上爬19 分钟前
Day01-postgresql数据库基础入门培训
数据库·postgresql
customer0827 分钟前
【开源免费】基于SpringBoot+Vue.JS美容院管理系统(JAVA毕业设计)
android·java·vue.js·spring boot·spring cloud·开源
Wang's Blog37 分钟前
Redis: 集群架构,优缺点和数据分区方式和算法
数据库·redis·架构
太自由1 小时前
SpringBoot之Profile的两种使用方式
java·spring boot·后端·profile·springboot多环境配置·profile注解
tiantian17)1 小时前
深入学习并发编程中的 synchronized
java·学习
fishmemory7sec1 小时前
Koa2+mongodb项目实战1(项目搭建)
数据库·mongodb·koa
kingapex11 小时前
性能优化-数据库分区技术深入解析
数据库·oracle·性能优化·数据库设计
mariokkm1 小时前
Django一分钟:使用prefetch_related避免陷入大量的查询中导致严重的性能问题
数据库·django·sqlite