NIO(New IO)和BIO(Blocking IO)的区别
Java中的NIO(New IO)和BIO(Blocking IO)的区别及NIO的核心组件
Java中的NIO(New IO)和BIO(Blocking IO)是两种不同的网络通信模型,各自具有独特的特性和适用场景。下面将详细探讨它们之间的区别以及NIO的核心组件。
BIO(Blocking IO)
BIO是Java最早的I/O模型,也是最简单的一种。在BIO模型中,每个I/O操作都会阻塞当前线程,直到数据准备就绪或者超时,才会继续执行下一步操作。这意味着如果有大量的并发连接,就需要创建大量的线程来处理这些连接,会造成资源浪费和性能下降。
BIO通常采用的是一对一的客户端-服务器模型,即每个客户端连接都需要对应一个服务器端的线程来处理。这样的模型适用于连接数较少且连接持续时间较长的场景,但不适合高并发、短连接的场景。例如,传统的Web服务器在处理HTTP请求时,如果采用BIO模型,那么每个客户端连接都需要一个独立的线程来处理,当并发连接数增加时,服务器的线程资源会迅速耗尽,性能会急剧下降。
BIO的优点是简单易懂,编程复杂度较低,适用于连接数较少且连接持续时间较长的场景。然而,在高并发情况下,BIO的性能较差,资源消耗大,因此在实际应用中逐渐被NIO等更高效的模型所取代。
NIO(New IO)
NIO是Java在JDK 1.4引入的新的I/O模型,相比于BIO,它提供了更为灵活和高效的网络编程方式。NIO的核心组件包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。
- 通道(Channel)
通道是Java NIO中用于数据读写的对象,类似于传统I/O中的流。但与传统I/O的流不同,通道支持非阻塞I/O操作,并且可以同时进行读写操作。这意味着线程在等待数据完全传输过来后才能处理数据,从而提高了系统的并发性。
通道是全双工的,即它可以同时用于读和写操作。常见的通道类型包括FileChannel(用于文件读写)、DatagramChannel(用于UDP网络读写)、SocketChannel(用于TCP网络读写)和ServerSocketChannel(用于监听TCP连接)。
- 缓冲区(Buffer)
缓冲区是NIO中用于在通道和应用程序之间传输数据的中介。它是一个对象,包含一些要写入或者读出的数据。在面向流的I/O中,可以将数据直接写入或读到Stream对象中,而在NIO中,所有的数据都是用缓冲区处理的。
缓冲区实质是一个数组,通常是一个字节数组(ByteBuffer),也可以使用其他类型的数组。除了ByteBuffer,还有其他类型的缓冲区,如CharBuffer(字符缓冲区)、ShortBuffer(短整型缓冲区)、IntBuffer(整型缓冲区)、LongBuffer(长整型缓冲区)、FloatBuffer(浮点型缓冲区)和DoubleBuffer(双精度浮点型缓冲区)。
缓冲区提供了对数据的结构化访问以及维护读写位置(limit)等信息。在数据读写过程中,需要不断切换缓冲区的读写模式,如flip()方法用于将缓冲区从写模式切换到读模式,clear()方法用于清空缓冲区以便下次使用。
- 选择器(Selector)
选择器是NIO中用于监听多个通道的事件的机制。它可以同时监听多个通道(Channel)的I/O事件,如读事件、写事件、连接事件等,使得一个单独的线程可以管理多个通道,进一步提高了系统的并发性。
选择器只能管理非阻塞的通道。当通道发生感兴趣的事件时,选择器会通知对应的线程进行处理。这样,一个线程就可以同时处理多个连接,避免了BIO模型中为每个连接创建一个线程的资源浪费。
NIO模型中的关键是非阻塞通道和选择器。通过使用单线程或少量线程配合选择器,可以实现同时处理多个连接,从而提高了系统的并发处理能力。NIO模型适用于高并发、短连接的场景,如Web服务器、游戏服务器等。它的设计理念是通过少量线程处理大量并发连接,避免了线程资源的浪费和上下文切换的开销,从而提高了系统的性能和吞吐量。
NIO的线程模型
NIO主要包含三种线程模型:Reactor单线程模型、Reactor多线程模型和主从Reactor多线程模型。
- Reactor单线程模型
在单线程模型中,单个线程完成所有事情,包括接收客户端的TCP连接请求、读取和写入套接字数据等。这种模型适用于一些小容量应用场景,但对于高负载、大并发的应用却不合适。因为单个NIO线程同时处理成百上千的链路,性能上无法支撑,即便NIO线程的CPU负荷达到100%,也无法满足海量消息的编码、解码、读取和发送。
- Reactor多线程模型
Reactor多线程模型与单线程模型最大的区别就是有一组NIO线程处理真实的I/O操作。该模型的特点是:
- 有一个专门的NIO线程(Acceptor线程)用于监听服务端,接收客户端的TCP连接请求。
- 网络I/O操作(读、写等)由一个NIO线程池负责。线程池可以采用标准的JDK线程池实现,它包含一个任务队列和N个可用的线程。由这些NIO线程负责消息的读取、解码、编码和发送。
- 一个NIO线程可以同时处理N条链路,但是一个链路只对应一个NIO线程,防止发生并发操作问题。
在绝大多数场景下,Reactor多线程模型都可以满足性能需求。但是,在极特殊应用场景中,一个NIO线程负责监听和处理所有的客户端连接可能会存在性能问题。例如,百万客户端并发连接,或者服务端需要对客户端的握手消息进行安全认证,认证本身非常损耗性能。在这些场景下,单独一个Acceptor线程可能会存在性能不足问题,为了解决性能问题,产生了第三种Reactor线程模型——主从Reactor多线程模型。
- 主从Reactor多线程模型
主从Reactor多线程模型与Reactor多线程模型的最大区别就是有一组NIO线程处理连接、读写事件。该模型的特点是:
- 服务端用于接收客户端连接的不再是一个单独的NIO线程,而是一个独立的NIO线程池(Acceptor线程池)。
- Acceptor接收到客户端TCP连接请求处理完成后(可能包含接入认证等),将新创建的SocketChannel注册到I/O线程池(sub reactor线程池)的某个I/O线程上,由它负责SocketChannel的读写和编解码工作。
- Acceptor线程池仅仅只用于客户端的登陆、握手和安全认证。一旦链路建立成功,就将链路注册到后端subReactor线程池的I/O线程上,由I/O线程负责后续的I/O操作。
即从多线程模型中由一个线程来监听连接事件和数据读写事件,拆分为一个线程监听连接事件,线程池的多个线程监听已经建立连接的套接字的数据读写事件。另外和多线程模型一样,有专门的线程池处理真正的I/O操作。
NIO与BIO的比较
NIO和BIO各有优缺点,适用于不同的应用场景。
- 编程复杂度
BIO编程简单易懂,适用于连接数较少且连接持续时间较长的场景。而NIO提供了非阻塞、多路复用的网络编程方式,编程复杂度较高,但适用于高并发、短连接的场景。
- 性能
BIO在高并发情况下性能较差,因为每个连接都需要一个独立的线程来处理,线程资源消耗大。而NIO通过非阻塞通道和选择器,可以实现同时处理多个连接,提高了系统的并发处理能力,性能优于BIO。
- 资源消耗
BIO在大量并发连接时,会创建大量的线程,造成资源浪费和性能下降。而NIO通过少量线程处理大量并发连接,避免了线程资源的浪费和上下文切换的开销,从而提高了系统的性能和吞吐量。
- 适用场景
BIO适用于连接数较少且连接持续时间较长的场景,如传统的Web服务器在处理HTTP请求时。而NIO适用于高并发、短连接的场景,如现代的Web服务器、游戏服务器等。
应用场景示例
在Java生态系统中,许多中间件和框架都涉及到了NIO和BIO的使用,以实现高性能的网络通信。以下是一些常见的中间件和框架的示例:
- Netty
Netty是一个高性能的异步事件驱动的网络应用框架,它基于NIO实现了网络通信的高性能和可扩展性。Netty广泛应用于分布式系统、即时通信系统等领域。
- Apache MINA
Apache MINA是一个基于Java的网络应用框架,提供了可扩展的高性能的基于NIO的网络通信。它与Netty类似,但有一些不同的设计理念和API。
- Tomcat
Tomcat是一个流行的Java Servlet容器,它在处理HTTP请求时可以选择使用NIO或BIO。通过配置Connector的协议,可以选择不同的I/O模型来处理请求,以满足应用程序的性能和需求。
- Jetty
Jetty是另一个流行的Java Servlet容器和Web服务器,它也支持使用NIO或BIO来处理网络连接。
- Apache HTTP Server
Apache HTTP Server是世界上最流行的Web服务器之一,它在处理HTTP请求时可以使用NIO或者传统的多线程模型。
- Redis
Redis是一个内存数据库,它的网络通信层使用了NIO来实现高性能的异步I/O。
- MySQL Connector/J
MySQL的Java连接器,它可以使用NIO来实现异步的数据库访问。
- Spring Framework
Spring Framework是一个全面的Java开发框架,其中的Spring Web模块在处理HTTP请求时可以选择使用NIO或者传统的阻塞I/O。
相关文章:
NIO(New IO)和BIO(Blocking IO)的区别
Java中的NIO(New IO)和BIO(Blocking IO)的区别及NIO的核心组件 Java中的NIO(New IO)和BIO(Blocking IO)是两种不同的网络通信模型,各自具有独特的特性和适用场景。下面将…...
ROS1入门教程6:复杂行为处理
一、新建项目 # 创建工作空间 mkdir -p demo6/src && cd demo6# 创建功能包 catkin_create_pkg demo roscpp rosmsg actionlib_msgs message_generation tf二、创建行为 # 创建行为文件夹 mkdir action && cd action# 创建行为文件 vim Move.action# 定义行为…...
碰撞检测算法之闵可夫斯基差集法(Minkowski Difference)
在游戏开发和机器人路径规划乃至于现在比较火的自动驾驶中,我们常常需要确定两个物体是否发生碰撞,有一种通过闵可夫斯基差集法求是否相交的算法,下面将介绍一下 闵可夫斯基差集法的优势 闵可夫斯基差集法优势: 可以处理复杂的…...
【唐叔学算法】第18天:解密选择排序的双重魅力-直接选择排序与堆排序的Java实现及性能剖析
引言 在数据排序的世界里,选择排序是一类简单而直观的算法,它通过不断选取未排序部分中的最小(或最大)元素来逐步构建有序序列。今天,我们将深入探讨两种基于选择思想的排序方法——直接选择排序和堆排序,…...
2008-2020年各省技术服务水平相关指标数据
2008-2020年各省技术服务水平相关指标数据 1.时间:2008-2020年 2.指标:行政区划代码、地区、年份、信息传输、软件和信息技术服务业城镇单位就业人员(万人)、软件业务收入(万元)、高技术产品出口额占商品出口额比重(%) 3.范围&…...
机器学习DAY4续:梯度提升与 XGBoost (完)
本文将通过 XGBoost 框架来实现回归、分类和排序任务,帮助理解和掌握使用 XGBoost 解决实际问题的能力。我们将从基本的数据处理开始,逐步深入到模型训练、评估以及预测。最后,将模型进行保存和加载训练好的模型。 知识点 回归任务分类任务…...
ML-Agents:训练配置文件(一)
注:本文章为官方文档翻译,如有侵权行为请联系作者删除 Training Configuration File - Unity ML-Agents Toolkit–原文链接 常见训练器配置 关于训练,您需要做出的首要决定之一是使用哪种训练器:PPO、SAC 还是 POCA。有些训练配置…...
【物联网技术与应用】 实验13:雨滴传感器实验
实验13 雨滴传感器实验 【实验介绍】 雨滴传感器或雨滴检测传感器用于检测是否下雨以及降雨。广泛应用于汽车的雨刷系统、智能照明系统和天窗系统。 【实验组件】 ● Arduino Uno主板* 1 ● USB数据线*1 ● 雨滴传感器* 1 ● 雨滴传感器调理板* 1 ● 面包板*1 ● 9V方型…...
帝国cms电脑pc站url跳转到手机站url的方法
本文讲解一下帝国cms电脑网站跳转到手机动态网站和手机静态网站的方法,笔者以古诗词网 www.gushichi.com为例,为大家介绍操作步骤。方法一:帝国pc站跳转到手机静态站 1、假设我们有帝国cms 电脑网站www.XXX.com,手机网站m.XXX.com …...
Django models中的增删改查与MySQL SQL的对应关系
在 Django 中,models 提供了一种高层次的抽象来与数据库进行交互,使得开发者可以使用 Python 代码而非直接编写 SQL 来执行增删改查(CRUD)操作。下面将详细介绍 Django 的 ORM(对象关系映射)操作如何对应到…...
双指针——快乐数
一.题目描述 202. 快乐数 - 力扣(LeetCode) 二.题目解析 我们要判断一个数是不是快乐数要通过它的三个性质来进行判断。这个数会一直变化,由它的各个位的平方和重新构成这个数。如果这个数在变化的过程中变成了1,那么就是快乐数…...
Docker 默认安装位置迁移
一、找到 Docker 默认安装位置 [roothost-192-168-0-1 ~]# docker info Client:Version: 26.1.0Context: defaultDebug Mode: falseServer:Containers: 31Running: 31Paused: 0Stopped: 0Images: 128Server Version: 26.1.0Storage Driver: overlay2Backing Filesystem:…...
jmeter跨进程实现变量共享-全局变量
jmeter跨进程实现变量共享-全局变量 例如:登录一次,后面业务进行多线程并发场景 新增一个setUp线程组,在setUp线程组下,添加登录接口 使用json提取器,提取token Authorization $.token 0添加BeanShell 后置处理程序…...
Vue.js组件(6):echarts组件
1 前言 本章主要对常用的echars图表展示进行基本的组件封装。使用该组件前需要在项目中引入echarts。官网:Apache ECharts npm install echarts --save 2 图表组件 2.1 折线图组件 组件属性:chartId,指定图表挂载div的id,注意不…...
yolov3算法及其改进
yolov3算法及其改进 1、yolov3简介2、yolov3的改进2.1、backbone的改进2.1.1、darknet19相对于vgg16有更少的参数,同时具有更快的速度和更高的精度2.1.2、resnet101和darknet53,同样具有残差结构,精度也类似,但是darknet具有更高的速度2.2、FPN2.3、anchor-base与grid-cell…...
Python + 深度学习从 0 到 1(02 / 99)
希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦 欢迎关注、订阅专栏 【深度学习从 0 到 1】谢谢你的支持! ⭐ 手写数字分类: Keras MNIST 数据集 手写数字分类…...
HTML+CSS+JS制作在线书城网站(内附源码,含5个页面)
一、作品介绍 HTMLCSSJS制作一个在线书城网站,包含首页、分类页、排行榜页、新书上架页、特惠专区页等5个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。 二、页面结构 1. 顶部导航栏 包含网站Logo、搜索框、用户登录/注册入口、购物车图…...
【FastAPI】中间件
【FastAPI】中间件 一、概述二、作用2.1 日志记录与监控2.2 身份验证与授权2.3 CORS(跨域资源共享)2.4 Gzip压缩2.5 会话管理2.6 自定义功能2.7 执行顺序 三、 总结四、相关链接 一、概述 FastAPI的中间件提供了一种强大的机制,允许开发者在…...
5个实用的设计相关的AI网站
在这个日新月异的数字时代,我们不断面临着新的挑战和机遇。随着人工智能(AI)技术的飞速发展,越来越多的AI工具开始融入到设计相关的工作流程中,极大地提升了工作效率和创作能力。今天,我非常兴奋地向大家介…...
STL 六大组件
C STL(标准模板库)主要由六大组件构成,它们相互协作,为C程序员提供了功能强大且高效的通用数据结构和算法工具,以下是对这六大组件的详细介绍: 1. 容器(Containers) 概述ÿ…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
