【Netty】NIO 简介 ( NIO 模型 | NIO 三大组件 | 选择器 Selector | 通道 Channel | 缓冲区 Buffer | NIO 组件分配 | 缓冲区示例 )

简介: 【Netty】NIO 简介 ( NIO 模型 | NIO 三大组件 | 选择器 Selector | 通道 Channel | 缓冲区 Buffer | NIO 组件分配 | 缓冲区示例 )

文章目录

I . NIO 模型

II . NIO 三大组件交互流程

III . NIO 缓冲区

IV . NIO 与 BIO 对比

V . NIO 线程分配

VI . 缓冲区 ( Buffer ) 示例





I . NIO 模型


NIO 简介 :



① NIO 概念 : NIO 全称为 Non-Blocking IO , 是非阻塞 IO , 与 BIO ( Blocking IO / 阻塞 IO ) 相对应 ;


② NIO 相对于 BIO 的改进 : NIO 在 BIO 的基础上 , 增加了 IO 的性能 ;


③ NIO 模型特点 : NIO 是同步非阻塞模型 , BIO 是同步阻塞模型 ;


④ NIO API 位置 : 在 Java 中 , NIO 定义在 java.nio 包中 ;


⑤ NIO 三大组件 :


通道 Channel : 相当于 BIO 中的 Socket , 用于传输数据 , 向客户端读写数据 ,

缓冲区 Buffer : 每个通道 ( Channel ) 都维护了一个数据缓冲区 ( Buffer ) ; 通道 ( Channel ) 可以读写 缓冲区 ( Buffer ) 中的数据 , 是双向的 ; 客户端 也是读写 缓冲区 ( Buffer ) 中的数据 ; 缓冲区 ( Buffer ) 是 通道 ( Channel ) 与 客户端 之间的缓冲区 ;

选择器 Selector : 选择器 ( Selector ) 根据客户端请求 , 选择指定的 通道 ( Channel ) 为客户端进行服务 ;





II . NIO 三大组件交互流程


NIO 服务器端 交互流程 :



① 启动线程 : 服务器端启动一个线程 ;


② 选择器 ( Selector ) 遍历 通道 ( Channel ) : 线程通过 选择器 ( Selector ) 不同的遍历各个 通道 ( Channel ) , 如果发现有 客户端 对应的 通道 ( Channel ) 有网络请求 , 那么开始处理该 通道 ( Channel ) 相关业务逻辑 ;


③ 通道 ( Channel ) 与 缓冲区 ( Buffer ) 交互 : 通道 ( Channel ) 可以 读写 缓冲区 ( Buffer ) 中的数据 ;


④ 缓冲区 ( Buffer ) 与 客户端交互 : 缓冲区 ( Buffer ) 与 客户端 进行数据读写交互 ;


image.png






III . NIO 缓冲区


缓冲区 机制 : 缓冲区 ( Buffer ) 向上与 通道 ( Channel ) 进行数据读写交互 , 向下与 客户端 进行数据读写交互 , 客户端 与 通道 ( Channel ) 不直接进行数据通信 ;



① 缓冲区 ( Buffer ) 作用 : 缓冲区 ( Buffer ) 是实现非阻塞机制的重要途径 ;


② 编程风格 : NIO 也称为 面向 缓冲区 编程 ;


③ BIO 阻塞机制 : BIO 中 客户端 与 服务器端 进行交互 , 需要阻塞等待服务器的响应 , 服务器在建立连接后 , 也需要阻塞等待客户端的后续数据 ;


④ NIO 非阻塞机制 : 客户端请求服务器端后 , 将请求数据写入服务器端的 缓冲区 ( Buffer ) 中 , 服务器端通过 选择器 ( Selector ) 轮询 通道 ( Channel ) , 查询 缓冲区 ( Buffer ) 中是否有请求数据 , 客户端不用阻塞等待服务器端响应 , 服务器端也不用阻塞等待客户端的请求 , 因此这里实现了非阻塞机制 ;



非阻塞说明 : 当选择器 ( Selector ) 选择某个 通道 ( Channel ) 时 , 服务器端线程 从通道 ( Channel ) 中读取用户请求的数据 , 读取完毕之后 , 处理该请求处理 , 如果没有读取到用户请求数据 , 就会轮询其它的 通道 ( Channel ) , 如果所有的 通道 ( Channel ) 都没有事件触发 , 线程做其它事情 , 不会在此阻塞等待用户数据 ;



基于事件驱动 : 选择器 ( Selector ) 可以感知到 通道 ( Channel ) 中的事件 , 线程就会处理与该通道 ( Channel ) 相关业务 , 如果 通道 ( Channel ) 没有触发事件 , 那么线程去做其它事 ;






IV . NIO 与 BIO 对比


1 . 数据处理方式对比 :



① BIO 数据处理方式 : BIO 以 流的方式读写数据 , 输入流 读取数据 , 输出流 写出数据 ; 输入流 和 输出流 又分别有 字节流 , 字符流 分类 ;


② NIO 数据处理方式 : NIO 以 缓冲区 ( Buffer ) 数据块的方式处理数据 , 该处理数据的效率 , 远远高于以 流 的方式读写数据的效率 ;


客户端 与 服务器交互时 , 客户端将数据 写入到 缓冲区 ( Buffer ) , 等待服务器端 通道 ( Channel ) 读取该缓冲区的数据 ;

服务器 与 客户端交互时 , 服务器将数据 通过 通道 ( Channel ) 写出到缓冲区中 , 等待 客户端 读取 ;


2 . IO 模型 阻塞类型对比 : BIO 是 同步阻塞 型 IO ; NIO 是 同步非阻塞 型 IO ;






V . NIO 线程分配


BIO 模型 : 在 BIO 模型中 , 如果 一万 客户端 与 服务器端保持连接通信 , 并进行数据交互 , 就需要有 一万个线程 维护这些操作 ;


BIO 模型中 , 10000 1000010000 客户端连接 , 对应 10000 1000010000 线程 ;



NIO 模型 : 在 NIO 模型中 , 如果 一万 客户端 与 服务器端保持连接通信 , 并进行数据交互 , 那么假设分配 100 100100 个线程 , 每个线程都有对应的 选择器 ( Selector ) , 每个 选择器 ( Selector ) 轮询 100 100100 个 通道 ( Channel ) , 每个 通道 ( Channel ) 对应 一个 缓冲区 ( Buffer ) ;


NIO 模型中 , 10000 1000010000 客户端连接 , 对应 10000 1000010000 个缓冲区 ( Buffer ) , 10000 1000010000 个 通道 ( Channel ) , 100 100100 个线程 ;






VI . 缓冲区 ( Buffer ) 示例


Buffer 有 7 77 个子类 , 分别对应 8 88 大基础数据 ( Boolean 除外 ) , 这里使用 IntBuffer 作示例说明 ;



缓冲区 ( Buffer ) 代码示例 :


需求 : 创建一个 存放 int 数据的 缓冲区 ( Buffer ) , 其容量为 8 88 , 将 8 88 个 int 值存入缓冲区 , 翻转后 , 按照存放顺序打印出来 ;


import java.nio.IntBuffer;


public class BufferDemo {
    public static void main(String[] args) {
        //创建一个存储 Int 类型数据的 Buffer , 可以存储 8 个 Int 数据
        IntBuffer buffer = IntBuffer.allocate(8);
        //向 Buffer 中写入数据
        for(int i = 0; i < buffer.capacity(); i ++){
            buffer.put(i);
        }
        //从 Buffer 中取出数据
        //先将 Buffer 翻转一下 , 然后读取 , 读出的数据与存储的数据顺序一样
        buffer.flip();
        //循环读取 buffer 中的 Int 数据, 维护了一个索引 ,
        //代表当前操作的数据索引 , 即 position
        while (buffer.hasRemaining()){
            System.out.println("position " + buffer.position() + " . " + buffer.get());
        }
    }
}


执行结果 :


position : 0 . 0
position : 1 . 1
position : 2 . 2
position : 3 . 3
position : 4 . 4
position : 5 . 5
position : 6 . 6
position : 7 . 7



目录
相关文章
|
1月前
|
消息中间件 缓存 Java
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
零拷贝技术 Zero-Copy 是指计算机执行操作时,可以直接从源(如文件或网络套接字)将数据传输到目标缓冲区, 而不需要 CPU 先将数据从某处内存复制到另一个特定区域,从而减少上下文切换以及 CPU 的拷贝时间。
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
|
2月前
|
Java
让星星⭐月亮告诉你,Java NIO之Buffer详解 属性capacity/position/limit/mark 方法put(X)/get()/flip()/compact()/clear()
这段代码演示了Java NIO中`ByteBuffer`的基本操作,包括分配、写入、翻转、读取、压缩和清空缓冲区。通过示例展示了`position`、`limit`和`mark`属性的变化过程,帮助理解缓冲区的工作原理。
38 2
|
3月前
|
Java
Netty BIO/NIO/AIO介绍
Netty BIO/NIO/AIO介绍
|
4月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
154 0
|
4月前
|
存储 网络协议 Java
【Netty 神奇之旅】Java NIO 基础全解析:从零开始玩转高效网络编程!
【8月更文挑战第24天】本文介绍了Java NIO,一种非阻塞I/O模型,极大提升了Java应用程序在网络通信中的性能。核心组件包括Buffer、Channel、Selector和SocketChannel。通过示例代码展示了如何使用Java NIO进行服务器与客户端通信。此外,还介绍了基于Java NIO的高性能网络框架Netty,以及如何用Netty构建TCP服务器和客户端。熟悉这些技术和概念对于开发高并发网络应用至关重要。
93 0
|
5月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
7月前
|
存储 监控 Java
深入探索Java语言的NIO(New I/O)技术
深入探索Java语言的NIO(New I/O)技术
|
5月前
|
Java
Java中的NIO编程详解
Java中的NIO编程详解
|
5月前
|
Java 大数据
如何在Java中进行网络编程:Socket与NIO
如何在Java中进行网络编程:Socket与NIO
|
5月前
|
Java
Java中的NIO编程详解
Java中的NIO编程详解