IO Vs NIO

一、IO(传统阻塞式)

全称‌:Input/Output(输入/输出)

定义‌:Java 1.0 引入的基础 I/O 模型,基于流(Stream)的同步阻塞操作,线程在读写数据时会阻塞直到操作完成。

二、NIO(新式非阻塞式)

‌全称‌:

官方名称:New I/O(Java 1.4 引入的新 I/O 库)

技术特性名称:Non-blocking I/O(非阻塞 I/O)

‌定义‌:基于通道(Channel)和缓冲区(Buffer)的同步非阻塞模型,支持多路复用(Selector)和零拷贝等高并发优化。

当采用阻塞式的模式时,需要通过accept、read、write这些阻塞式函数进行连接的创建,数据的读取和写出,函数返回必须等待这个动作的完成。

当调用accept时,必须有新的连接进来时,函数才会返回,并产生新的连接对象。

当调用read时,必须得有数据存在时或者连接断开时,函数才会返回,返回值代表读取到的数据量或者小于0代表连接断开。

当调用write时,必须等待所发送的数据完全发送完毕或连接断开时,函数才会返回。

基于阻塞的因素,导致软件无法把多个连接的操作放置在一个线程内,因为如果这样操作,一旦一个连接发生了阻塞,那么其它连接就无法顺利操作下去。所以在这种模式下,通常需要为每个连接配置独立线程,读线程是必须的,写线程依赖业务逻辑,或许可以混合在读线程中(如果写总是发生在读信息之后)。

阻塞式模式,意味着10000个连接,至少必须开启10000个线程为匹配业务,这个对系统的资源开销太大了。

而非阻塞式IO则是为了解决上述问题,以达到高并发的目的。其实最终还是要完成连接的创建、数据的读写,设计思想在于是否能够在做这些操作之前,提前知道是否有数据可读或是否有空间可写呢?

是的,操作系统都提供了一些内核到用户态的通知消息,以通知新的连接创建到达、某个连接当下有多少数据可读,某个连接当下有多少缓存区可写入数据进行发送。

基于上述的这些通知机制,内部管理注册的多个(10000个)连接,接收对应的通知消息,则可以知道每个连接的状态,当外部轮训调用select函数时,返回可读或可写的连接,在这个基础上,外部再进行read或者write。read返回当前可读到的数据,write写入缓存可写入,不再一次性强制写完,函数返回真真写入的数据量。

简单来说,在系统的accept、read和write基础上,添加了一个逻辑层,这一层内通过系统的通知消息,获知每个连接的状态信息,从而在通过这一层对应函数调用时,进行连接的状态判别,避免调用进入系统级别的阻塞式流程。

Java采用java.nio.channels.Selector类达成NIO的异步逻辑层。

相关推荐
青山木3 分钟前
Hot 100 --- 划分字母区间
java·数据结构·算法·leetcode·贪心算法
Zzzzmo_6 分钟前
SpringBoot 配置文件
java·spring boot
君顾111 分钟前
外卖CPS小程序开发实战指南:从零到上线的完整流程
java·开发语言·外卖
無a伟12 分钟前
RabbitMq高级特性:消息确认,持久化,重试机制
java·分布式·rabbitmq
blue_ice .14 分钟前
DDS原理及简易实现
开发语言·经验分享·笔记·嵌入式硬件·fpga开发
励志不掉头发的内向程序员17 分钟前
【LibreCAD 2D架构】鼠标点下的坐标为什么会被“吸”走?LibreCAD 对象捕捉系统解析
开发语言·c++·qt·学习·系统架构
流烟默21 分钟前
xxl-job 接入 Spring 的两种方式:手动装配与自动装配(含 initMethod 双启动踩坑实录)
java·spring·xxl-job
鹅城剑仙22 分钟前
Spring Boot 3 全局异常处理与统一响应封装进阶实战
java·spring boot·后端
Generalzy24 分钟前
像 gofmt 一样格式化 Python:Black、Ruff、YAPF、autopep8 谁才是 2026 年的首选?
开发语言·python
朝朝辞暮i28 分钟前
C++第一课
开发语言·c++·算法