BIO、NIO、AIO基本概念

BIO

采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成后,通过输出流返回应答给客户端,线程销毁。

BIO主要的问题在于每当有一个新的客户端请求接入时,服务端必须创建一个新的线程来处理这条链路,在需要满足高性能、高并发的场景是没法应用的(大量创建新的线程会严重影响服务器性能,甚至罢工)。

为了改进这种一连接一线程的模型,我们可以使用线程池来管理这些线程。但是,正因为限制了线程数量,如果发生大量并发请求,超过最大数量的线程就只能等待,直到线程池中有空闲的线程可以被复用。所以在读取数据较慢时(比如数据量大、网络传输慢等),大量并发的情况下,其他接入的消息,只能一直等待,这就是最大的弊端。

BIO方式适用于连接数目比较小且固定的场景,并且一次发送大量数据的场景,这种方式对服务器资源要求比较高,并发局限于应用中。

NIO

NIO提供了与传统BIO模型中的Socket和ServerSocket相对应的SocketChannel和ServerSocketChannel两种不同的套接字通道实现。

NIO适合处理连接数目特别多,但是连接比较短(轻操作)的场景,Jetty,Mina,ZooKeeper等都是基于java nio实现。

NIO的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,所以所有的连接只需要一个线程就可以搞定,当这个线程中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。

在NIO的处理方式中,当一个请求来的话,开启线程进行处理,可能会等待后端应用的资源(JDBC连接等),其实这个线程就被阻塞了,当并发上来的话,还是会有BIO一样的问题。
在这里插入图片描述

AIO

AIO需要操作系统的支持,在linux内核2.6版本中加入了对真正异步IO的支持,java从jdk1.7开始支持AIO。

与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。 在JDK1.7中,这部分内容被称作NIO.2,主要在java.nio.channels包下增加了下面四个异步通道:

AsynchronousSocketChannel
AsynchronousServerSocketChannel
AsynchronousFileChannel
AsynchronousDatagramChannel
其中的read/write方法,会返回一个带回调函数的对象,当执行完读取/写入操作后,直接调用回调函数。

异步通道 API 提供两种对已启动异步操作的监测与控制机制。第一种是通过返回一个 java.util.concurrent.Future 对象来实现,它将会建模一个挂起操作,并可用于查询其状态以及获取结果。第二种是通过传递给操作一个新类的对象,java.nio.channels.CompletionHandler,来完成,它会定义在操作完毕后所执行的处理程序方法。

热门文章

暂无图片
编程学习 ·

Ubuntu 18.04安装docker-compose

安装docker-compose之前先安装docker环境可以参照我的文章https://blog.csdn.net/weixin_42608885/article/details/106859553#安装依赖工具 $ sudo apt-get install python-pip -y #安装编排工具 $ sudo pip install docker-compose #查看版本 $ sudo docker-compose version
暂无图片
编程学习 ·

Mathmatica多项式带余除法代码

几乎没有调用内置函数,除了求多项式最高次数时用了一下 Exponent[] (*解析多项式*) (*将f=a0+a1*x+...+an*x^n解析成{{a0,0},{a1,1},...,{an,n}}的形式*) polyCoefficients[f_] := Module[{rules1 = {c_*base_^power_ -> {c, power},base_^power_ -> {1, power},c_*x_ -…
暂无图片
编程学习 ·

DAY14 Javaweb Servlet、Response、Request

以下讲的都是最底层的内容,以后会被新的方法顶替掉一、Servlet,是sun公司开发的一门技术,如果要开发sevlet程序(网页java),只需要1、实现这个接口就可以 2、把开发好的java类部署到web服务器中。把实现了Servlet接口的Java程序叫做Servlet,一个请求地址对应一个servlet…
暂无图片
编程学习 ·

kafka+zookeeper消息队列

软件包提取码:u3s1 kafka: 起初是做采集日志的,和zookeeper一起才能做消息队列,可持久化。kafka broker(server): 消息中间件处理的节点 一个Kafka节点就是一个broker(server) topic = vhost -类消息 对消息进行分类主题-个类型-个主题topic可以有多个 partition = que…
暂无图片
编程学习 ·

训练数据转换为PASCAL VOC2007

数据 我们已有标注数据个数为json保存的,现在训练代码使用的标注格式为PASCAL VOC2007,为了不修改代码,将数据转换到PASCAL VOC2007的xml格式。 转换代码 import os import json from lxml.etree import Element, SubElement, tostring, ElementTree from xml.dom import mi…
暂无图片
编程学习 ·

Docker的帮助和镜像命令

帮助命令 docker version 查看docker版本 docker info 显示全系统信息 docker --help 显示docker相关的所有命令 镜像命令 列表镜像 docker images 列表本机上的镜像REPOSITORY --表示镜像的仓库源 TAG --表示镜像的标签 IMAGE ID --镜像的ID CREATED --镜像的创建时间 SIZE --…
暂无图片
编程学习 ·

云管理服务AWS Organizations正式在AWS中国区域上线

近期, AWS中国(宁夏)区域(由西云数据运营)和AWS中国(北京)区域(由光环新网运营)正式上线了云管理服务AWS Organizations。作为一种管理服务,AWS Organizations可集中控制和管理多个AWS账户,无论是初创公司还是大型企业均可以使用,而不需要额外付费。随着企业或机构…
暂无图片
编程学习 ·

安装JDK

安装JDK 前提 要准备好jdk的包:jdk-8uxxx-linux-x64.tar.gz //JAVA 8 版本都可以 笔者这里使用的171 下载地址:Java SE 8 存档下载. 步骤 一、 解压jdk:tar -zxvf jdk-8u171-linux-x64.tar.gz二、 设置环境变量,编辑文件添加如下: vi /etc/profile export JAVA_HOME=/us…
暂无图片
编程学习 ·

CSS 总结

一、CSS三大特性:层叠性、继承性、优先级 层叠性 层叠性:就近原则。 分两种情况:同类选择器,第二个选择器样式会覆盖第一个选择器样式。 在同一个选择器中,相同的属性会以最后一个为准。继承性 继承性:子承父业 特殊:a标签不受影响因为它又自己的特性 优先级 优先级选择…
暂无图片
编程学习 ·

Codeforces 1342 E Placing Rooks —— 第二类斯特林数

This way 题意: 现在有一个n*n的棋盘,n个棋子,你要放置这些棋子使得他们满足以下条件: 每个格子都能被某个棋子打到 共有k对棋子能够打到对方 如果一个格子所处的这一行或这一列有一个棋子,那么这个格子就能被打到。两个棋子处在同一行或同一列并且它们之间没有别的棋子,…
暂无图片
编程学习 ·

JAVA中的集合(概述)

JAVA中的集合(概述)什么是集合,有什么用? 数组其实就是一个集合,集合实际上就是一个容器,可以用来容纳其他类型数据集合为什么说在开发中使用较多? 集合是一个容器,是一个载体,可以一次容纳多个对象。在实际开发中,假设连接数据库, 数据库中有10条记录,那么假设把这…
暂无图片
编程学习 ·

free_spirit(在栈上爆破一个可以被free的fake_chunk)

free_spirit(在栈上爆破一个可以被free的fake_chunk)首先检查一下程序的保护机制然后,我们用IDA分析一下,功能3存在8字节溢出,将会把v7下面的buf指针覆盖掉,而覆盖了buf指针,就能实现任意地址写。那么,我们劫持函数栈返回地址为one_gadget即可,为了绕过结尾对buf的检查…
暂无图片
编程学习 ·

C#中常见的简答题(第三天)

8.简述ADO.NET中五个主要对象A.Connection:主要是开启程序和数据库之间的连接。没有利用连接对象将数据库打开,是无法从数据库中取得数据的。Close和Dispose的区别,Close以后还可以Open,Dispose以后则不能再用。B.Command:主要可以用来对数据库发出一些指令,例如可以对数据…
暂无图片
编程学习 ·

java6----break与continue

1:continue的例子 package java1;public class java3 {public static void main(String[] args) {for (int i = 1; i <= 20; i++) {if (i % 4 == 0) {continue;//跳过本轮循环 ,也就是跳过下面的输出,进行下一次的for循环}System.out.print(i + " ");}} } /* 1…
暂无图片
编程学习 ·

Object类的方法

Object 类是类层次结构的根,在 Java 语言中,所有的类从根本上而言都继承自这个类。而且,Object 类是 Java 语言中唯一没有父类的类,而其他所有的类,包括标准容器类,例如数组,都继承了 Object 类。方法名 返回类型 方法描述clone() Object 创建并返回此对象的一个副本equ…
暂无图片
编程学习 ·

Go 结构体使用注意事项和细节

结构体使用注意事项和细节结构体的所有字段在内存中是连续的//结构体 type Point struct {x inty int }//结构体 type Rect struct {leftUp, rightDown Point }func main() {r1 := Rect{Point{1,2}, Point{3,4}}//r1有四个int, 在内存中是连续分布//打印地址fmt.Printf("…
暂无图片
编程学习 ·

从永远到永远-SpringCloud项目实战(七)-前端框架NUXT

1、什么是服务端渲染 服务端渲染又称SSR (Server Side Render)是在服务端完成页面的内容,而不是在客户端通过AJAX获取数据。 服务器端渲染(SSR)的优势主要在于:更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。 如果你的应用程序初始展示 loading 菊花图,…
暂无图片
编程学习 ·

java枚举enum

java枚举 jdk5.0之前的 public class SessonTest {public static void main(String[] args) {Seasson spring = Seasson.Spring;System.out.println(spring);} }class Seasson{//1.private final String seassonName;private final String seassonDesc;//2.private Seasson(Str…