IO、BIO、NIO、AIO

1、基础知识点

1.1、同步与异步

        关注的是被调用方的执行方式及返回时机
        同步:被调用方做完内部所有事情后再返回,同步调用的调用者一定会得到被调用方的结果。
        异步:被调用方先返回,再做事情,做完所有事情后再通知调用方(回调方法),异步调用方不会立即得到被调用方的结果,而是当被调用方执行完成后通过回调函数处理该结果。

1.2、阻塞与非阻塞

        关注的是调用方在被调用方返回结果之前的这段时间,是否处于等待状态
        阻塞:调用方在等待被调用方返回结果的这段时间什么都不干;
        非阻塞:调用方在等待被调用方返回结果的这段时间去处理其他事情。

1.3.同步/异步与阻塞/非阻塞对比

        同步/异步从行为角度描述事物,针对的对象是被调用方,主要关注被调用方的执行方式及返回时机。
        阻塞/非阻塞描述当前事物的状态(等待调用结果时的状态),针对的对象是调用方,主要关注调用方是否在等待被调用方返回结果的这段时间是否处于等待状态。

1.4、并发与并行

        并发:一个时间段内,几个程序都在同一个CPU上运行,但任意一个时刻点上只有一个程序在处理机上运行。
        并行:一个时间段内,几个程序在不同的CPU上运行,任意一个时刻点上,有多个程序在同时运行,并且多道程序之间互不干扰。

2、I/O

        I/O是Input输入/Output输出的简称,通常指数据在内部存储器(内存外部存储器(硬盘、优盘或其他周边设备之间的输入和输出。
  输入/输出是信息处理系统(计算机)与外部世界(人类或另一信息处理系统)之间的通信。

3、BIO 

       BIO (blocking-io,同步阻塞I/O)模式,数据的读取写入必须阻塞在一个线程内等待其完成。

3.1、BIO通信模型:一请求一应答

        采用BIO通信模型的服务端,一般由一个独立的Acceptor线程负责监听客户端的连接,一般通过while(true)循环中服务端会调用accept()方法等待接收客户端的连接的方式监听请求;一旦接收到一个客户端的连接请求,就可以建立通信套接字在这个通信套接字上进行读写操作,此时当前线程不能再接收其他客户端连接请求,只能等待当前客户端的操作执行完成(可通过多线程来支持多个客户端的连接)
   一请求一应答通信模型:服务端接收到客户端连接请求后为每个客户端创建一个新的线程进行链路处理,处理完成后,通过输出流返回应答给客户端,线程销毁。
   客户端并发访问量增加后一请求一应答模型的弊端:若连接不做任何事情就会造成不必要的线程开销,在Java虚拟机中,线程是宝贵的资源,线程的创建、销毁、切换成本很高,如果并发量增加会导致线程数急剧膨胀可能会导致线程堆栈溢出、创建新线程失败等问题,最终导致服务端不能对外提供服务。

socket流程图:   

​​​​​​​

 

        解决一请求一应答模型的弊端,后端通过一个线程池来处理多个客户端的请求接入,形成客户端个数M:线程池最大线程数N的比例关系,M可以远大于N,通过线程池就可以灵活的调配线程资源,避免每个请求都创建一个独立线程造成的线程资源耗尽,并设置线程池最大值,防止由于海量并发接入导致线程耗尽。
        当活动连接数不是特别高(小于1000),BIO模型比较实用,每个连接专注于自己的I/O且编程模型简单,线程池本身是个天然的漏斗,可以缓冲一些系统处理不了的连接或请求,当若面对上百万级连接时,BIO无能为力。

4、NIO(New I/O,Non-Block I/O)

        同步非阻塞的I/O模型,支持面向缓冲的,基于通道的I/O操作方法,提供SocketChannel和ServerSocketChannel并支持阻塞(与BIO一样)与非阻塞两种模式。对于低负载、低并发的应用程序可以使用同步阻塞I/O提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用使用NIO的非阻塞模式。

        jdk提供的nio的代码在:java.nio包下。

4.1、IO与NIO区别

4.1.1、IO流是阻塞的,NIO的非阻塞的

        IO:IO各种流是阻塞的,当线程调用read()或write()时,该线程被阻塞,直到一些数据被读取或数据完全写入,该线程在此期间不能再干任何事情了。
        NIO:NIO可以进行非阻塞IO操作,比如:单线程从通道读取数据到buffer,同时继续做别的事情,当数据读取到buffer后,线程再继续处理数据。写数据也是一样的,一个线程请求写入一些数据到某通道,不需要等待它完全写入,这个线程同时可以去做别的事情。

4.1.2、IO是面向流的,NIO是面向缓冲区的

        IO:面向流的IO可以将数据直接写入或将数据直接读到Stream对象中。
        NIO:NIO直接读到Buffer中进行操作,所有数据都是用缓冲区处理的,读取数据是直接读到缓冲区,写入数据也是直接写入到缓冲区,任何时候访问NIO中的数据,都是通过缓冲区进行操作。

NIO通过Channel(通道)进行读写
    Channel通道是双向的,可读也可写,而流是单向的。无论读写,通道只能与Buffer交互,通道可以异步的读写。

4.2、NIO有Selector选择器

        Selector选择器用于使用单个线程处理多个通道,只需要较少的线程来处理这些通道,线程之间切换对于操作系统来讲是昂贵的,因此选择器会提高系统效率。
        Thread->Selector->Channel1/Channel2/Channel3

NIO(多selector)模型图:

4.3、NIO读写数据方式

        NIO中所有的IO都是从Channel(通道)就开始的
        从通道进行数据读取:创建一个缓冲区,然后请求通道读取数据->(Channel->Buffer)
        从通道进行数据写入:创建一个缓冲区,填充数据,并要求通道写入数据->(Buffer->Channel)

4.4、nio的几个概念

4.4.1、Channel:

        Channel是一个对象,可以通过它读取和写入数据。拿 NIO 与原来的 I/O 做个比较,通道就像是流,而且他们面向缓冲区的。

        所有数据都通过 Buffer 对象来处理。您永远不会将字节直接写入通道中,相反,您是将数据写入包含一个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

        通道与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类), 而 通道 可以用于读、写或者同时用于读写。

        因为它们是双向的,所以通道可以比流更好地反映底层操作系统的真实情况。特别是在 UNIX 模型中,底层操作系统通道是双向的。

4.4.2、缓冲区:

        缓冲区 是一个固定数据量的指定基本类型的数据容器。除内容之外,缓冲区还具有位置 和界限,其中位置是要读写的下一个元素的索引,界限是第一个应该读写的元素的索引。基本 Buffer 类定义了这些属性以及清除、反转 和重绕 方法,用以标记 当前位置,以及将当前位置重置 为前一个标记处。

        每个非布尔基本类型都有一个缓冲区类。每个类定义了一系列用于将数据移出或移入缓冲区的 get 和 put 方法,用于压缩、复制 和切片 缓冲区的方法,以及用于分的异类或同类二进制数据序列),访问要么是以 big-endian字节顺序进行,要么是以 little-endian 字节顺序进行。

5、AIO

        AIO是异步IO,在读取数据的整个过程都是异步的,当数据准备好之后,直接由操作系统内核缓冲区将数据复制到用户缓冲区,整个过程不需要用户线程做什么。
        但AIO现在还没有广泛应用,现在的大公司服务端采用的都是多路复用IO模型(NIO),特点是支持高并发。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340