Java I/O模型发展以及Netty网络模型的设计思想
Java I/O模型发展以及Netty网络模型的设计思想
- I/O模型
- Java BIO
- Java NIO
- Java AIO
- NIO Reactor网络模型
- 单Reactor单线程模型
- 单Reactor多线程模型
- 主从Reactor多线程模型
- Netty通信框架
前言:
BIO、NIO的代码实践参考:Java分别用BIO、NIO实现简单的客户端服务器通信
I/O模型
- I/O:I和O指
input和output,输入输出 - 通俗理解:用怎么样的通道进行
数据的发送和接收 - 很大程度上决定程序通信的性能
Java共支持三种I/O模型:BIO,NIO,AIO
BIO:同步阻塞,一个线程处理一个连接。只要有一个客户端连接到服务器就需要开一个线程。同一个线程的连接和读写操作会阻塞NIO:同步非阻塞,一个线程处理多个连接。实现方式是客户端的请求事件都会注册到多路复用器(selector)上面,多路复用器进行轮询处理AIO:异步非阻塞,引入异步通道概念,采用Proactor模式,有效请求事件才会启动线程,特点是先由操作系统完成后才通知服务器程序启动线程,适用于连接数多的长连接请求
Java BIO
流程:
- 服务器启动一个
ServerSocket - 客户端启动
socket与服务器通信。服务器需要对每个客户端建立一个线程 - 客户端发出请求后,先咨询服务器有无线程响应,没有则等待
- 有响应,客户端会等待请求结束后再继续执行

Java NIO
主要概念:
- 三大核心:
Channel(通道),Buffer(缓冲区),Selector(多路复用器) - 非阻塞模式:一个线程从通道请求或读取数据时,它仅能得到能用的数据,无可用数据时,不会阻塞线程,可以继续做其他事情,非阻塞写也是一样,不需要等待写入
- 通俗理解:NIO可以做到用一个线程处理多个操作,假设有10000个请求,实际可能只需要开50-100个线程,不像BIO一样必须分配10000个线程
- HTTP2.0也使用了
多路复用技术,做到了一个连接并发处理多个请求,数量比HTTP1.0大了好几个数量级
Channel(通道),Buffer(缓冲区),Selector(多路复用器)的关系:
- 每个Channel对应一个Buffer
- Selector对应一个线程,一个线程对应多个Channel
- Selector根据不用事件,在各个通道上切换
- Buffer是一个内存块,底层是数组,读写切换需要用flip()
- Channel是双向的,可以返回底层操作系统的情况
Channel:
- BIO的stream是单向的
- Channel是双向的,可以读也可以写
- 常见的Channel还有FileChannel,DatagramChannel,SocketChannel,ServerSocketChannel
- FileChannel:文件读写
- DatagramChannel:UDP读写
- SocketChannel,ServerSocketChannel:TCP读写
NIO编程流程:
- 服务器启动一个
ServerSocket得到一个ServerSocketChannel - 创建一个服务器的
Selector - ServerSocketChannel注册到Selector上,标记为连接事件,Selector监听该事件
- 开始循环
- Selector得到有事件的
SelectorKey集合,并进行轮询 - 使用SelectorKey上绑定的Channel进行业务处理(连接,读,写)

Java AIO
NIO Reactor网络模型
单Reactor单线程模型
方案:
Selector是网络编程API,可以实现应用程序对多路链接请求的处理- 服务器用一个
多路复用器即一个Reactor监听所有的客户端的请求连接、读、写事件 - 每次处理完连接,会创建一个
Handler处理连接后的读写业务处理 - Handler负责完成整个读、业务处理、写业务流程
优缺点:
- 代码简单,只有一个线程,清晰明了
- 客户端连接较多时,无法支撑
- 一般的NIO实现样例就是用的这种模型(Java分别用BIO、NIO实现简单的客户端服务器通信)

单Reactor多线程模型
方案:
Selector是网络编程API,可以实现应用程序对多路链接请求的处理- 服务器用一个多路复用器即一个
Reactor监听所有的客户端的请求连接、读、写事件 - 每次处理完连接,会创建一个Handler处理连接后的读写业务处理
- Handler只响应事件,读取数据,不做业务处理,分发给
worker线程池里面的线程处理业务 - worker线程池分配一个线程负责完成业务处理、回传等业务流程
优缺点:
- 可以充分利用多核cpu处理能力
- 多线程数据访问和共享比较复杂
- Reactor同样是单线程,相比于单Reactor单线程模型性能好一些,但是高并发场景同样会遇到性能瓶颈

主从Reactor多线程模型
方案:
Reactor主线程和Reactor从线程,主线程负责处理连接事件,从线程负责处理读写事件- 主Reactor通过
Acceptor处理完连接事件后,主Reactor把连接分给从Reactor处理 - 从Reactor将连接的channel注册到Selector中进行监听,并创建各种
Handler进行处理 - Handler只响应事件,读取数据,不做业务处理,分发给
worker线程池里面的线程处理业务 - worker线程池分配一个线程负责完成业务处理、回传等业务流程
优缺点:
- 主线程和从线程数据交互简单,职责明确
- 能处理较大并发量
- 编程复杂度较高

Netty通信框架
主要基于主从Reactor多线程模型,做了一定的改进,增加了Reactor线程池,可以多个主线程和多个从线程并发处理
Netty模型图(简单版)

Netty模型图(复杂版)

工作原理:
- netty抽象出两种线程池
BossGroup,WorkGroup,分别做连接事件多路复用和网络读写事件多路复用 - BossGroup,WorkGroup都是
NioEventLoopGroup - NioEventLoopGroup相当于事件循环组,组中有多个
NioEventLoop事件循环 - NioEventLoop表示一个不断循环的执行处理任务的线程,每个NioEventLoop都有一个
多路复用器Selector - 每个BossGroup中的NioEventLoop执行步骤是: a. 轮询
accept事件 b. 处理accept事件,与客户端建立连接,生成channel,并将其注册到某个WorkGroup中的NioEventLoop上的Selector c. 处理任务队列的任务,即runAllTask - 每个WorkGroup中的NioEventLoop执行步骤是: a. 轮询
read,write事件 b. 处理read,write事件,主要是处理channel c. 处理任务队列的任务,即runAllTask - 每个WorkGroup中的NioEventLoop处理业务时,会使用
pipeline管道,pipeline包含了channel,pipeline维护了很多handler处理器

相关文章:
Java I/O模型发展以及Netty网络模型的设计思想
Java I/O模型发展以及Netty网络模型的设计思想 I/O模型Java BIOJava NIOJava AIO NIO Reactor网络模型单Reactor单线程模型单Reactor多线程模型主从Reactor多线程模型 Netty通信框架 前言: BIO、NIO的代码实践参考:Java分别用BIO、NIO实现简单的客户端服…...
智能电网时代:数字孪生的崭露头角
随着科技的不断进步,数字孪生已经开始在电力行业崭露头角,为这个关键的行业带来了前所未有的机遇和潜力。本文就带大家了解一下数字孪生在哪些方面为电力行业做出改变,以及未来的创新应用。 首先,数字孪生可以提高电力系统运营效率…...
每日一题 501二叉搜素树中的众数(中序遍历)
题目 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 任意顺序 返回。 假定 BST 满足如下定义&a…...
测试理论与方法----测试流程第三个环节:设计测试用例
测试流程第三个环节:设计测试用例:怎么测<——>测试需求的提取:测什么 ### 5、测试用例 描述:测试用例(TestCase):是一份关于【具体测试步骤】的文档,是为了达到最佳的测试效果或高效揭露软件中潜藏的…...
C++多态案例2----制作饮品
#include<iostream> using namespace std;//制作饮品的大致流程都为: //煮水-----冲泡-----倒入杯中----加入辅料//本案例利用多态技术,提供抽象类制作饮品基类,提供子类制作茶叶和咖啡class AbstractDrinking {public://煮水//冲水//倒…...
机械零件保养3d模拟演示打消客户购买顾虑
复杂机械的工作运转是复杂的,想要对机械有深度的理解和迭代,必须了解它的运转原理及参数,复杂机械运行原因教学存在着不可视、系统庞杂及知识点多等弊病,3D虚拟展示是基于web3d网页运行的三维页面,可以将复杂机械运行过…...
SpringBoot的自动装配源码分析
文章目录 一:什么是自动装配二、springboot的启动流程1.调用SpringApplication()的构造方法2.执行核心run方法()3.执行核心prepareContext()4.执行核心refreshContext()5…...
Linux常用命令——csplit命令
在线Linux命令查询工具 csplit 将一个大文件分割成小的碎片文件 补充说明 csplit命令用于将一个大文件分割成小的碎片,并且将分割后的每个碎片保存成一个文件。碎片文件的命名类似“xx00”,“xx01”。csplit命令是split的一个变体,split只…...
React 组件的3大属性: state
state 一、理解二、用途三、使用3.1、类初始化3.2、函数初始化 四、状态读更4.1、组件内部状态管理和数据更新4.2、state 和 props 一起使用 一、理解 组件被称为"状态机", 页面的显示是根据组件的state 属性的数据来显示。 state 是一个用于存储和管理组件内部数据的…...
vscode 上传项目到gitlab
第一步初始化项目 如果没有创建过分支(创建分支这里不记录),默认是master分支: ①将所需要的上传的文件添加到暂存区,如图: ②填写一下注释信息,将暂存区的文件上传到本地分支(没有创…...
[羊城杯 2020] easyphp
打开题目,源代码 <?php$files scandir(./); foreach($files as $file) {if(is_file($file)){if ($file ! "index.php") {unlink($file);}}}if(!isset($_GET[content]) || !isset($_GET[filename])) {highlight_file(__FILE__);die();}$content $_GE…...
QT 常用类与组件
0 思维导图 1 信息调试类(QDebug) #include "widget.h" #include<iostream> //printf #include<QDebug> //qDebuf using namespace std; //coutWidget::Widget(QWidget *parent): QWidget(parent) {//输出函数//使用…...
C#控制台连接Mysql数据库,有配置数据库连接字符串的配置文件
C#控制台连接Mysql数据库,有配置数据库连接字符串的配置文件 实现功能 读取..txt 中的配置文件,来初始化连接字符串让连接字符串的配置文件不存在会主动创建默认的连接字符串 注意点: 需要引用Newtonsoft使用mysql 代码如下 using Syst…...
PowerBuilder连接SQLITE3
PowerBuilder,一个古老的IDE,打算陆续发些相关的,也许还有人需要,内容可能涉及其他作者,但基本都是基于本人实践整理,如涉及归属,请联系. SQLite,轻型数据库,相对与PowerBuilder来说是个新事务,故发数来,以供参考. PB中使用OLE Microsoft OLE DB方式进行连接,如下 // Profile…...
Git 基本原理和常用操作
Git Git 是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。由 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开源的版本控制软件。 Git 常用操作 git 提交流程:工作区 -> git add 到暂存区 -> gi…...
单元测试和集成测试的区别
单元测试和集成测试是软件开发中常用的两种测试方法,它们的主要区别如下: 范围不同:单元测试关注于对软件中的最小功能单元进行测试,通常是对独立的函数、方法或类进行测试。而集成测试则更加综合,涉及多个模块、组件或…...
node基础概念
前言:可以让别人访问我们的网页,可以开发服务端应用、工具类应用、桌面端应用(electron) 1. 计算机基础 概念:CPU 内存 硬盘 主板 显卡 2. 进程和线程 概念:进程是一个程序的执行,线程组合形…...
ArcGIS Maps SDK for JS(二):MapView简介----创建2D地图
文章目录 1 AMD 引用 ArcGIS Maps SDK for JavaScript2 加载相应模块3 创建地图4 创建 2D 视图 view5 确定页面内容6 CSS 样式7 完整代码 本教程使用 AMD 模块,指导您如何在二维地图视图中创建一个简单的地图。 1 AMD 引用 ArcGIS Maps SDK for JavaScript 在 <…...
知识图谱推理研究综述9.3
综述分类 根据样本量大小的不同,将知识图谱推理方法分为多样本推理、少样本推理和零与单样本推理 KG定义:(Y) 知识图谱是以图的形式表示真实世界的实体与关系之间关系的知识库。 具体来说知识图谱是通过将应用数学、图形学、信…...
详细介绍c++中的类
C 中的类是面向对象编程的基本概念,它指的是一种能够封装数据和方法的用户定义数据类型。类是程序中一个重要的概念,它允许程序员通过定义类来实现代码复用、模块化和继承等特性。 C 中的类由以下部分组成: Data members:成员变量…...
力扣算法面试150题——个人笔记——复习用
双指针 第一题: 125. 验证回文串https://leetcode.cn/problems/valid-palindrome/ 题目内容 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母…...
【云计算学习之路】学习Centos7系统-Linux网络配置管理
Linux网络TCP/IP协议概述OSI 七层模型与 TCP/IP 四层模型 协议对照表IP地址及网络常识IP地址A类IP地址B类IP地址C类IP地址D类IP地址特殊的网址子网掩码网关地址MAC地址Linux服务器IP命名规范Linux服务器网卡及主机名命名Linux服务器上网DNS设置Linux服务器默认网卡配置文件在/e…...
5秒完成B站缓存视频转换:m4s到MP4无损转换完整指南
5秒完成B站缓存视频转换:m4s到MP4无损转换完整指南 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾为B站缓存视频无法在其他…...
告别手动传图!用PicGo+Gitee给Typora配个自动图床(保姆级配置+避坑清单)
打造无缝Markdown写作体验:自动化图床配置全攻略 在技术写作和知识管理的世界里,Markdown已经成为事实上的标准格式。然而,一个长期困扰写作者的问题始终存在——图片管理。传统方式需要手动上传图片到图床,复制链接,再…...
《CVPR2025-DEIM创新改进项目实战:从原理到部署的深度学习优化全攻略》004、DEIM数学基础:注意力机制与特征重标定的统一框架
CVPR2025-DEIM创新改进项目实战:从原理到部署的深度学习优化全攻略 004、DEIM数学基础:注意力机制与特征重标定的统一框架 一、从一次诡异的梯度爆炸说起 去年秋天调一个轻量级检测模型,在T4上跑得好好的,换到Jetson Orin上就炸了——loss直接飞到NaN。查了三天,最后定…...
加速3DGS生成与数字孪生开发:不可错过的8款效率工具盘点
一、行业核心技术科普:3DGS数字孪生开发的工具链概览一个高效的3DGS数字孪生开发流程,离不开一套完整的工具链。从数据采集、模型生成、格式优化到应用开发与部署,每个环节都有其专用的工具。其域创新围绕“感知—重建—理解—创造”的技术路…...
英雄联盟个性化工具终极指南:3分钟免费打造专属游戏身份
英雄联盟个性化工具终极指南:3分钟免费打造专属游戏身份 【免费下载链接】LeaguePrank 项目地址: https://gitcode.com/gh_mirrors/le/LeaguePrank 想要在英雄联盟中展示与众不同的个人资料吗?LeaguePrank是一款开源免费的英雄联盟个性化工具&am…...
GitLab团队协作实战:从分支策略到CI/CD流水线优化指南
1. 项目概述:为什么需要一个专属的GitLab使用指导?在团队协作开发中,版本控制系统是基石,而GitLab作为集代码托管、CI/CD、项目管理于一体的DevOps平台,其重要性不言而喻。然而,对于许多新加入团队的开发者…...
紧急!你的灵感工作流正在被Perplexity范式淘汰:3个信号预警+2天迁移 checklist(含Prompt审计表)
更多请点击: https://codechina.net 第一章:紧急!你的灵感工作流正在被Perplexity范式淘汰:3个信号预警2天迁移 checklist(含Prompt审计表) 当你反复修改同一个提示词却仍得不到结构化输出,当团…...
嵌入式学习的第八天
字符指针常见错误 核心:字符串常量存只读内存,不可修改! #include <stdio.h> int main() {// 错误写法:指针指向字符串常量(只读),不能修改内容char *p "hello"; // *(p0) e…...
