【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 ) 与 客户端 进行数据读写交互 ;


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






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



上一篇:分析现有 WPF / Windows Forms 程序能否顺利迁移到 .NET Core 3.0(使用 .NET Core 3.0 Desktop API Analyzer )


下一篇:解密:Struts2漏洞及其补丁漏洞“曝光”纪实