16.BIO、NIO、AIO 有什么区别?

2023-11-16

简单介绍

  • BIO 就是传统的 java.io包,它是基于流模型实现的,交互的方式是同步、阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前,线程会一直阻塞在那里,它们之间的调用时可靠的线性顺序。它的优点就是代码比较简单、直观;缺点就是 IO 的效率和扩展性很低,容易成为应用性能瓶颈。
  • NIO 是 Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。
  • AIO 是 Java 1.7 之后引入的包,是 NIO 的升级版本,提供了异步非堵塞的 IO 操作方式,所以人们叫它AIO(Asynchronous IO),异步 IO是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

详细介绍

本文内容涉及同步与异步,阻塞与非阻塞,BIO、NIO、AIO等概念,这块内容本身比较复杂,很难用三言两语说明白,而书上的定义更不容易理解是什么意思。下面这些内容是按照我的理解,以我认为尽可能简单易懂的语言组织出来,希望能够帮助理解这些概念。
1. 同步与异步

同步与异步的概念,关注的是 消息通信机制

同步是指发出一个请求,在没有得到结果之前该请求就不返回结果,请求返回时,也就得到结果了。
比如洗衣服,把衣服放在洗衣机里,没有洗好之前我们一直看着, 直到洗好了才拿出来晾晒。

异步是指发出一个请求后,立刻得到了回应,但没有返回结果。这时我们可以再处理别的事情(发送其他请求),所以这种方式需要我们通过状态主动查看是否有了结果, 或者可以设置一个回调来通知调用者。

比如洗衣服时,把衣服放到洗衣机里,我们就可以去做别的事情,过会儿来看看有没有洗好(通过状态查询);或者我们设置洗衣机洗完后响铃来通知我们洗好了(回调通知)

2. 阻塞与非阻塞

阻塞与非阻塞很容易和同步与异步混淆,但两者关注点是不一样的。 阻塞与非阻塞关注的是 程序在等待调用结果时的状态

  • 阻塞是指请求结果返回之前,当前线程会被挂起(被阻塞),这时线程什么也做不了
  • 非阻塞是指请求结果返回之前,当前线程没有被阻塞,仍然可以做其他事情。

阻塞有个明显的特征就是线程通常是处于BLOCKED状态(BIO中的read()操作时,线程阻塞是JVM配合OS完成的,此时Java获取到线程的状态仍是RUNNABLE但它确实已经被阻塞了)

如果要拿同步来做比较的话,同步通信方式中的线程在发送请求之后等待结果这个过程中应该处于RUNNABLE状态,同步必须一步一步来完成,就像是代码必须执行完一行才能执行下一行, 所以必须等待这个请求返回之后才可进行下一个请求, 即使等待结果的时间长,也是在执行这个请求的过程中。而异步则不用等上一条执行完, 可以先执行别的代码,等请求有了结果再来获取结果。

3. IO模型

Java中的IO操作是JVM配合操作系统来完成的。对于一个IO的读操作,数据会先被拷贝到操作系统内核的缓冲区中,然后从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以整个过程可分为两个阶段:

  1. 等待I/O数据准备好,这取决于IO目标返回数据的速度, 如网络IO时看网速和数据本身的大小。
  2. 数据从内核缓冲区拷贝到进程内。

根据这两个阶段,产生了常见的几种不同的IO模型:BIONIOIO多路复用AIO

3.1 BIO
BIOBlocking I/O(阻塞 I/O),BIO整个过程如下图:
在这里插入图片描述

程序发送请求给内核,然后由内核去进行通信,在内核准备好数据之前这个线程是被挂起的,所以在两个阶段程序都处于挂起状态。

  • BIO的特点就是在IO执行的两个阶段都被block了

3.2 NIO
NIONon-Blocking I/O(非阻塞 I/O), NIO整个过程如下图:
在这里插入图片描述

与BIO的明显区别是,发起第一次请求后,线程并没有被阻塞,它反复检查数据是否准备好,把原来大块不能用的阻塞时间分成了许多“小阻塞”(检查),所以进程不断有机会被执行。这个检查有没有准备好数据的过程有点类似于“轮询”。

  • NIO的特点就是程序需要不断的主动询问内核数据是否准备好。第一个阶段非阻塞,第二个阶段阻塞

3.3 IO多路复用

IO多路复用(I/O Multiplexing)有selectpollepoll等不同方式,它的优点在于单个线程可以同时处理多个网络IO。

NIO中轮询操作是用户线程进行的,如果把这个任务交给其他线程,则用户线程就不用这么费劲的查询状态了。IO多路复用调用系统级别的selectpoll模型,由系统进行监控IO状态。select轮询可以监控许多socket的IO请求,当有一个socket的数据准备好时就可以返回。

  • select: 注册事件由数组管理, 数组是有长度的, 32位机上限1024, 64位机上限2048。轮询查找时需要遍历数组。

  • poll:把select的数组采用链表实现,因此没了最大数量的限制

  • epoll方式:基于事件回调机制,回调时直接通知进程,无须使用某种方式来查看状态。

多路复用IO过程图:
在这里插入图片描述

用户线程有一段时间是阻塞的,从上图来看,与NIO很像,但与NIO不一样的是,select不是等到所有数据准备好才返回,而是只要有一个准备好就返回,它的优势在于可以同时处理多个连接。若连接不是很多的话,它的效率不一定高,可能还会更差。

Java 1.4开始支持NIO(New IO),就是采用了这种方式,在套接字上提供selector选择机制,当发起select() 时会阻塞等待至少一个事件返回。

  • 多路复用IO的特点是用户进程能同时等待多个IO请求,系统来监控IO状态,其中的任意一个进入读就绪状态,select函数就可以返回。

3.4 AIO

AIOAsynchronous I/O(异步 I/O),这是Java 1.7引入的NIO 2.0中用到的。整个过程中,用户线程发起一个系统调用之后无须等待,可以处理别的事情。由操作系统等待接收内容,接收后把数据拷贝到用户进程中,最后通知用户程序已经可以使用数据了,两个阶段都是非阻塞的。AIO整个过程如下图:
在这里插入图片描述

AIO属于异步模型, 用户线程可以同时处理别的事情,我们怎么进一步加工处理结果呢? Java在这个模型中提供了两种方法:

  • 一种是基于”回调”,我们可以实现CompletionHandler接口,在调用时把回调函数传递给对应的API即可

  • 另一种是返回一个Future。处理完别的事情,可以通过isDone() 可查看是否已经准备好数据,通过get()方法等待返回数据。

3.5 小结

上面这几种模式,BIO整个过程都等待返回,NIOIO多路复用在第二个阶段等待返回,因此从整个过程来看,这三个模式都属于同步方式。 AIO在整个过程中没有等待返回,属于异步方式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

16.BIO、NIO、AIO 有什么区别? 的相关文章

随机推荐

  • C/C++配置使用windows msys2中的gcc/g++编译器

    介绍 比较常见的 可以在Windows上安装各种工具链来编译C和C 应用程序 如果是专门为Windows开发的 那是推荐Microsoft 免费提供的Visual Studio Community 出色的IDE工具 对于那些需要或喜欢跨平台
  • LeetCode 45 跳跃游戏 II(Java)

    题目 给你一个非负整数数组 nums 你最初位于数组的第一个位置 数组中的每个元素代表你在该位置可以跳跃的最大长度 你的目标是使用最少的跳跃次数到达数组的最后一个位置 假设你总是可以到达数组的最后一个位置 示例1 输入 nums 2 3 1
  • 前端 华为OBS 上传图片和查看图片

    前提是OBS 使用的是SDK BrowserJS 下载SDK BrowserJS 1 前提 npm config set registry https registry npmjs org 2 esdk obs browserjs 3 20
  • 【转】Visual Studio 2010下配置PC-Lint 9.0i

    转自 http blog csdn net jbcjay article details 7389543 首先下载PC Lint安装包 可以到CSDN资源区搜索下载 或者直接到我上传的资源区下载 一 安装过程 下载完安装包后可以直接点击pc
  • 仅需四步,整合SpringSecurity+JWT实现登录认证 !

    学习过我的mall项目的应该知道 mall admin模块是使用SpringSecurity JWT来实现登录认证的 而mall portal模块是使用的SpringSecurity基于Session的默认机制来实现登陆认证的 很多小伙伴都
  • Redis( stringRedisTemplate)添加缓存数据

    在redis中添加缓存数据大致思路 1 从redis中获取数据 如果存在 直接返回客户端 2 不存在 查询数据库 并写入redis缓存 3 如果从数据库查询为空 返回错误信息 4 写入redis缓存并返回数据 通过String类型添加商品数
  • Java如何用JDBC操作数据库(新手入门级)

    引入相关依赖包 想要用JDBC操作数据库 我们就必须要下载JDBC相关的依赖 这些依赖其实就是我们用来操作数据库的代码 那么什么是JDBC呢 JDBC就是 Java DataBase Connectivity 的简称 是数据库连接的意思 J
  • MapXtreme 2005 for .Net系列------MapControl初尝

    这一段时间在闲暇时看看mapXtreme 2005 for net 自己觉得与AE庞大复杂的结构相比 mapXtreme 可谓简单点 由于规模比较小 所以理解起来比较简单 本来先发一篇综述的帖子 不过由于条件的限制 自己现将这篇帖子发出来
  • 独家

    翻译 张媛 校对 卢苗苗 本文共8269字 建议阅读10分钟 用代码将你的数据集进行多维可视化 介绍 描述性分析是与数据科学或特定研究相关的任何分析生命周期中的核心组成部分之一 数据聚合 汇总与可视化是支撑数据分析这一领域的主要支柱
  • 通过css设置filter 属性,使整个页面呈现灰度效果,让整个网页变灰

    通过css设置filter 属性设置页面整体置灰 效果图 通过设置 filter 属性为 grayscale 100 页面中的所有元素都会被应用灰色滤镜效果 使整个页面呈现灰度效果 filter 属性是用来给元素添加不同的滤镜 graysc
  • Qt自定义界面类并提升(提升的窗口部件),把OpenGL绘制的图形显示在QT的ui界面上

    编译环境 Qt Creator 5 4 0 mingw 最近利用QT做一个上位机界面 想用OpenGL将STL文件还原成三维模型 并将模型显示出来 那么问题来了 最简单的显示就直接创建一个窗口显示模型 根本就 没有用到QT的ui界面 现在的
  • JAVA区块链实战教程-杨长江-专题视频课程

    JAVA区块链实战教程 256人已学习 课程介绍 国内第一套以java语言讲解区块链原理的教程 包含实际项目和代码 让java从业人员 快速了解区块链和区块链原理 课程收益 1 区块链理论 以node js例子区块链原理有深刻理解 2 区块
  • 一个简单的外部系统调用接口日志记录demo

    一 实现思想 抽取接口共方法 作为抽象类 然后不同业务实现类继承此抽象类 实现具体业务 分析可知公共部分就是将外系统入参和接口返回参数记录到数据库 将其抽取出来 作为基础抽象类的公共方法 业务类继承此抽象类 使得不用在每一个业务实现类里面重
  • Selenium基础 — Selenium自动化测试框架介绍

    1 什么是selenium Selenium是一个用于Web应用程序测试的工具 只要在测试用例中把预期的用户行为与结果都描述出来 我们就得到了一个可以自动化运行的功能测试套件 Selenium测试套件直接运行在浏览器中 就像真正的用户在操作
  • spring+springMVC+MyBatis 分页功能代码封装

    页面效果图展示 分页工具类 Pagination package com wlsq kso util import java io Serializable import java util ArrayList import java ut
  • 【uniapp】原生子窗体subNvue的使用与踩坑

    需求 最近接到个需求 需要在video组件上弹出弹窗 也就是覆盖video这个原生组件 未播放时 弹窗可以覆盖 但是当video播放时 写的弹窗就覆盖不了了 因为video是原生组件 层级非常高 普通标签是覆盖不了的 map标签同理 覆盖原
  • 【前端】Bad control character in string literal in JSON解决方案(详解),JSON.parse(str)/Uncaught SyntaxEr报错解决方法。

    问题描述 let text fail station FSW WELDING DRY 2 r n fail resourceid 200118223 r n fail timestamp 2022 12 17 JSON parse text
  • 宝塔部署Springboot项目与踩坑

    目录 1 宝塔硬件方面 2 转储数据库 3 开放端口 4 打包maven项目 1 宝塔硬件方面 首先在宝塔上安装完成mysql与Tomcat 然后在MySQL的配置文件中添加 skip grant tables 重载配置并启动 注意可能会启
  • tomcat下CSS失效

    项目改界面的时候 把新界面套用到原有页面上去 总是不正常 有部分CSS显示不出来 弄了半天才发现 原来是tomcat缓存的问题 把tomcat的缓存 也就是work文件夹下的相关文件删除就正常了 具体原因好像是因为 tomcat的jsp文件
  • 16.BIO、NIO、AIO 有什么区别?

    简单介绍 BIO 就是传统的 java io包 它是基于流模型实现的 交互的方式是同步 阻塞方式 也就是说在读入输入流或者输出流时 在读写动作完成之前 线程会一直阻塞在那里 它们之间的调用时可靠的线性顺序 它的优点就是代码比较简单 直观 缺