阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO 一文搞定

异步 IO 基础原理:select, poll, epoll 当谈论 IO(以及大多数情况下一般的异步编程)时,异步意味着我们不会阻塞等待 IO 完成的线程。因此,如果用户从操作系统请求一些 IO,并且操作系统执行 IO 而不返回,然后在完成后返回结果,即同步(也称为阻塞)IO。使用异步 IO,用户请求 IO,然后可以继续处理其他事情,当 IO 完成时,获取结果。// Synchronous 同步// Async 异步注意,我们仅讨论单个用户线程。我们总是可以通过使用多个线程来使事情异步,但这并不是大多数人在谈论异步 IO 或异步编程时的意思。 阅读详情

关于IO会涉及到阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO等几个知识点。知识点虽然不难但平常经常容易搞混,特此Mark下,与君共勉。

1 阻塞跟非阻塞

1.1 阻塞

​阻塞IO情况下,当用户调用read后,用户线程会被阻塞,等内核数据准备好并且数据从内核缓冲区拷贝到用户态缓存区后read才会返回。可以看到是阻塞的两个部分。

  1. CPU把数据从磁盘读到内核缓冲区。

  2. CPU把数据从内核缓冲区拷贝到用户缓冲区。

1.2 非阻塞

非阻塞IO发出read请求后发现数据没准备好,会继续往下执行,此时应用程序会不断轮询polling内核询问数据是否准备好,当数据没有准备好时,内核立即返回EWOULDBLOCK错误。直到数据被拷贝到应用程序缓冲区,read请求才获取到结果。并且你要注意!这里最后一次 read 调用获取数据的过程,是一个同步的过程,是需要等待的过程。这里的同步指的是内核态的数据拷贝到用户程序的缓存区这个过程。

1.3 IO多路复用

​非阻塞情况下无可用数据时,应用程序每次轮询内核看数据是否准备好了也耗费CPU,能否不让它轮询,当内核缓冲区数据准备好了,以事件通知当机制告知应用进程数据准备好了呢?应用进程在没有收到数据准备好的事件通知信号时可以忙写其他的工作。此时IO多路复用就派上用场了。

IO多路复用中文比较让人头大,IO多路复用的原文叫 I/O multiplexing,这里的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流. 发明它的目的是尽量多的提高服务器的吞吐能力。实现一个线程监控多个IO请求,哪个IO有请求就把数据从内核拷贝到进程缓冲区,拷贝期间是阻塞的!现在已经可以通过采用mmap地址映射的方法,达到内存共享效果,避免真复制,提高效率。

​像select、poll、epoll 都是I/O多路复用的具体的实现。

1.3.1 select

select是第一版IO复用,提出后暴漏了很多问题。

  1. select 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的。

  2. select 如果任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但不会告诉是那个sock上有数据,只能自己遍历查找。

  3. select 只能监视1024个链接。

  4. select 不是线程安全的,如果你把一个sock加入到select, 然后突然另外一个线程发现这个sock不用,要收回,这个select 不支持的。

1.3.2 poll

poll 修复了 select 的很多问题。

  1. poll 去掉了1024个链接的限制。

  2. poll 从设计上来说不再修改传入数组。

但是poll仍然不是线程安全的, 这就意味着不管服务器有多强悍,你也只能在一个线程里面处理一组 I/O 流。你当然可以拿多进程来配合了,不过然后你就有了多进程的各种问题。

1.3.3 epoll

epoll 可以说是 I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比如:

  1. epoll 现在是线程安全的。

  2. epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。

  3. epoll 内核态管理了各种IO文件描述符, 以前用户态发送所有文件描述符到内核态,然后内核态负责筛选返回可用数组,现在epoll模式下所有文件描述符在内核态有存,查询时不用传文件描述符进去了。

1.3.4 三者对比

​横轴 Dead connections 是链接数的意思,叫这个名字只是它的测试工具叫deadcon。纵轴是每秒处理请求的数量,可看到epoll每秒处理请求的数量基本不会随着链接变多而下降的。poll 和/dev/poll 就很惨了。但 epoll 有个致命的缺点是只有linux支持。

比如平常Nginx为何可以支持4W的QPS是因为它会使用目标平台上面最高效的I/O多路复用模型。

1.4 异步IO

​然后你会发现上面的提到过的操作都不是真正的异步,因为两个阶段总要等待会儿!而真正的异步 I/O 是内核数据准备好和数据从内核态拷贝到用户态这两个过程都不用等待。

很庆幸,Linux给我们准备了aio_read跟aio_write函数实现真实的异步,当用户发起aio_read请求后就会自动返回。内核会自动将数据从内核缓冲区拷贝到用户进程空间,应用进程啥都不用管。

【文章福利】另外小编还整理了一些C++后端开发面试题,教学视频,后端学习路线图免费分享,需要的可以自行添加:学习交流群点击加入~ 群文件共享

小编强力推荐C++后端开发免费学习地址:C/C++Linux服务器开发高级架构师/C++后台开发架构师https://ke.qq.com/course/417774?flowToken=1013189

2 同步跟异步

2.1 同步

同步跟异步的区别在于数据从内核空间拷贝到用户空间是否由用户线程完成,这里又分为同步阻塞跟同步非阻塞两种。

  1. 同步阻塞:此时一个线程维护一个连接,该线程完成数据到读写跟处理到全部过程,数据读写时时线程是被阻塞的。

  2. 同步非阻塞:非阻塞的意思是用户线程发出读请求后,读请求不会阻塞当前用户线程,不过用户线程还是要不断的去主动判断数据是否准备OK了。此时还是会阻塞等待内核复制数据到用户进程。他与同步BIO区别是使用一个连接全程等待

我们以同步非阻塞为例,如下可看到,在将数据从内核拷贝到用户空间这一过程,是由用户线程阻塞完成的。

2.2 异步

对于异步来说,用户进行读或者写后,将立刻返回,由内核去完成数据读取以及拷贝工作,完成后通知用户,并执行回调函数(用户提供的callback),此时数据已从内核拷贝到用户空间,用户线程只需要对数据进行处理即可,不需要关注读写,用户不需要等待内核对数据的复制操作,用户在得到通知时数据已经被复制到用户空间。我们以如下的真实异步非阻塞为例。

​可发现,用户在调用之后会立即返回,由内核完成数据的拷贝工作,并通知用户线程,进行回调。

2.3 同步跟异步对比

同步关注的消息通信机制synchronous communication,在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。

异步关注消息通信机制asynchronous communication,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

3 Java IO

在Java中,我们使用socket进行网络通信,IO主要有三种模式,主要看内核支持哪些。

  1. BIO:同步阻塞IO。

  2. NIO:同步非阻塞IO。

  3. AIO:异步非阻塞IO。

3.1 BIO

同步阻塞IO,每个客户端的Socket连接请求,服务端都会对应有个处理线程与之对应,对于没有分配到处理线程的连接就会被阻塞或者拒绝。相当于是一个连接一个线程。

​BIO特点:

  1. 使用一个独立的线程维护一个socket连接,随着连接数量的增多,对虚拟机造成一定压力。

  2. 使用流来读取数据,流是阻塞的,当没有可读/可写数据时,线程等待,会造成资源的浪费。

3.1.1 BIO 样例

常量:

public class Constant {
    public static final String HOST = "127.0.0.1";
    public static final int PORT = 8080;
}

主类:

public class ClientMain {
    public static void main(String[] args) {
        //开启服务
        System.out.println("开启服务,监听端口:" + Constant.PORT);
        new Thread(new ServerThread()).start();
        //建立一个socket客户端,发起请求
        System.out.println("客户端,请求连接,并发送数据");
        try {
            Socket socket = new Socket(Constant.HOST,Constant.PORT);
            //开启新的线程处理socket连接
            new Thread(new ClientProcessThread(socket)).start();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

服务端监听线程:

// 开启服务监听线程,当收到连接请求后,开启新的线程进行处理
public class ServerThread implements Runnable{
    @Override
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(Constant.PORT);
            while (true){
                Socket socket = serverSocket.accept();
                new Thread(new ServerProcessThread(socket)).start();
                //开启新的线程进行连接请求的处理
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务端处理线程:

import java.io.*;
import java.net.Socket;
/**
 * 服务端收到连接请求后,处理请求的线程,阻塞式IO
 */
public class ServerProcessThread implements Runnable {
    private Socket socket;
    public ServerProcessThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        //获取客户端的数据,并写回
        //等待响应
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = "";
            String requestStr = "";
            System.out.println("来自客户端的数据:"); // 读取客户端数据
            while((line = bufferedReader.readLine()) != null){
                requestStr += line;
                System.out.println(line);
            }
            //  从服务端发给客户端数据
            Writer writer = new OutputStreamWriter(socket.getOutputStream());
            writer.write("data from server " + requestStr + "\r\n");
            writer.flush();
            writer.close();
            bufferedReader.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端:

3.2 NIO

同步非阻塞IO之NIO:服务器端保存一个Socket连接列表,然后对这个列表进行轮询,如果发现某个Socket端口上有数据可读时说明读就绪,则调用该socket连接的相应读操作。如果发现某个 Socket端口上有数据可写时说明写就绪,则调用该socket连接的相应写操作。如果某个端口的Socket连接已经中断,则调用相应的析构方法关闭该端口。这样能充分利用服务器资源,效率得到了很大提高,在进行IO操作请求时候再用个线程去处理,是一个请求一个线程。Java中使用Selector、Channel、Buffer来实现上述效果。

每个线程中包含一个Selector对象,它相当于一个通道管理器,可以实现在一个线程中处理多个通道的目的,减少线程的创建数量。远程连接对应一个channel,数据的读写通过buffer均在同一个channel中完成,并且数据的读写是非阻塞的。通道创建后需要注册在selector中,同时需要为该通道注册感兴趣事件(客户端连接服务端事件、服务端接收客户端连接事件、读事件、写事件),selector线程需要采用轮训的方式调用selector的select函数,直到所有注册通道中有兴趣的事件发生,则返回,否则一直阻塞。而后循环处理所有就绪的感兴趣事件。以上步骤解决BIO的两个瓶颈:

  1. 不必对每个连接分别创建线程。

  2. 数据读写非阻塞。

下面对以下三个概念做一个简单介绍,Java NIO由以下三个核心部分组成:

  1. selector:Selector 允许单线程处理多个Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。要使用Selector,得向Selector注册Channel,然后调用他的select方法,这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子入有新连接接进来,数据接收等。

  2. Channel:基本上所有的IO在NIO中都从一个Channel开始。Channel有点像流,数据可以从channel读到buffer,也可以从buffer写到channel。

  3. Buffer:缓冲区本质上是一个可以读写数据的内存块,可以理解成是一个容器对象(含数组),该对象提供了一组方法,可以更轻松的使用内存块,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变换情况,Channel提供从文件,网络读取数据的渠道,但是读取或者写入的数据都必须经由Buffer。

channel和buffer有好几种类型。下面是Java NIO中的一些主要channel的实现:

FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel

正如你所看到的,这些通道涵盖了UDP和TCP网络IO,以及文件IO。以下是Java NIO里关键的buffer实现:

ByteBuffer
CharBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer

在微服务阶段,一个请求可能涉及到多个不同服务之间的跨服务器调用,如果你想实现高性能的PRC框架来进行数据传输,那就可以基于Java NIO做个支持长连接、自定义协议、高并发的框架,比如Netty。Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。比如Dubbo底层就是用的Netty。

3.3 AIO

AIO是异步非阻塞IO,相比NIO更进一步,进程读取数据时只负责发送跟接收指令,数据的准备工作完全由操作系统来处理。

参考资料

推荐一个零声教育C/C++后台开发的免费公开课程,个人觉得老师讲得不错,分享给大家:C/C++后台开发高级架构师,内容包括Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

原文:阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO 一锅端

BIO、NIO、AIO 介绍和适用场景分析 机会是留给有准备的人,大家在求职之前应该要明确自己的态度,熟悉求职流程,做好充分的准备,把一些可预见的事情做好。对于应届毕业生来说,校招更适合你们,因为绝大部分都不会有工作经验,企业也不会有工作经验的需求。同时,你也不需要伪造高大上的实战经验,以此让自己的简历能够脱颖而出,反倒会让面试官有所怀疑。你在大学时期应该明确自己的发展方向,如果你在大一就确定你以后想成为Java工程师,那就不要花太多的时间去学习其他的技术语言,高数之类的,不如好好想着如何夯实Java基础。请转发本文支持一下。 阅读详情

相关推荐

Amesim(五):单个悬架系统搭建

一、组成 单个悬架系统组成包括:端子,质量块*2,弹簧,阻尼器,速度路面反馈,路面激励。 二、搭建 打开Amesim,在 library 选择 1D Mechanical 选择质量模块,添加到skech中,并按 ctrl+r 旋转质量块,将箭头朝上,设置规定的力传递正方向 添加弹簧阻尼器,与质量块连接 添加VX模块,将路面的激励传递转化为速度和位移,传递给悬架系统 在...

林小川的博客 7166

IO模型-异步I/O模型

异步I/O模型是进程通过系统调用告知内核启动某个I/O操作,内核启动I/O操作后立刻返回到进程,进程在I/O操作发生期间继续执行程序,当IO操作完成或遭遇错误时,内核以进程在I/O系统调用中指定的某种方式通知进程操作结果。说明首先用户态进程告诉内核态需要什么数据,然后用户态进程继续执行程序,内核等待用户态需要的数据准备好,然后将数据复制到用户空间,操作完成后才告诉用户态进程结果,然后用户态进程直接处理用户空间的数据。在复制数据到用户空间这个时间段内,用户态进程在正常执行程序。.........

weixin_44614002的博客 2340

【论文笔记】Beyond Low-frequency Information in Graph Convolutional Networks

文章目录1. Abstract2. Introduction低频和高频信号作用FAGCN怎么设计3. An Experimental Investigation4. Model4.1 filter定义4.2 Aggregation4.3 Problems of signal combination4.4 Spatial vision of FAGCN4.5 系数αijG\alpha_{i j}^{G}αijG​4.6 模型整体框架FAGCN的表达能力实验 本文发表在AAAI-21上 论文地址:https:

Running Snail 5601

阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO 一锅端

因为申请较晚,本公众号没留言,想交流的欢迎添加私人微信,一起相互吹捧,共同进步。承接上文的操作系统,关于IO会涉及到阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO等几个知识点。...

sowhat 1224

【LVGL】学习笔记--(3)界面切换以及显示优化

界面切换和帧率优化

sinat_33408502的博客 1万+

高频面波成像实战:从频散曲线到全波形反演

面波勘探是近地表工程勘察的重要手段,其核心原理在于不同频率的面波对地下介质的敏感深度不同,由此形成的频散曲线能够反映浅层剪切波速结构。相较于传统钻探与折射波法,高频面波成像具有无损、高效、对低速夹层敏感等优势,广泛应用于路基检测、空洞探测、滑坡调查等领域。在实际工程中,从野外采集的排列设计、震源选型,到频散谱提取与频散曲线反演,每一步都直接影响成像精度。然而频散反演受限于一维层状假设,难以刻画横向剧烈变化的地质体。全波形反演通过拟合完整波形信息,能够突破频散曲线的分辨率边界,获得更精细的近地表速度模型。本文

weixin_29090917的博客 269

同步IO、异步IO以及五种网络IO模式

当用户进程调用了select,那么整个进程就会被block,而同时,kernel会 “监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。很显然,这种IO模型是同步的。有一天,学校里面优化了热水的供应,增加了很多水龙头,这个时候小明同学再去装水,舍管阿姨告诉他这些水龙头都还没有水,你可以去忙别的了,等有水了告诉他。: 小明去打开水,而开水塔此时没有水,开水塔的阿姨叫小明把水壶放到现场,来水后会帮他打好水,并打电话叫他来取,这是异步IO的一种案例。

m0_65635427的博客 2572

Contest 226 - C - Martial artist

from atcoder Problem Statement Time Limit: 2 sec / Memory Limit: 1024 MB Score :300300points Takahashi is a martial artist. There areNNmoves that a martial artist can learn, called Move11,22,\ldots…,NN. For each1 \leq i \leq N1≤i≤N, it takes...

m0_54674275的博客 1020

阻塞IO、非阻塞IO和IO多路复用

当内核进程访问数据没有准备好时,立即返回一个失败信息,告诉用户进程没有准备好,用户进程不断的重新调用数据,也就是不断的问内核准备好了没有,在这段时间内核在后台会持续尝试将硬件上的数据读取到缓冲区。直达某一刻,数据准备好了,也到达内核了,访问不在报错,尝试拷贝并返回数据。先调用select函数,select内部可以接收多个fd,也就是可以吧每个客户端的Socket对应的FD都可以传给select函数,然后传入到内核,内核检查这些FD是否有准备就绪的,只要有一个准备就绪的,就调用recvfrom函数处理。

qq_55931044的博客 413

Rclone替代RaiDrive?零广告免费挂载Alist WebDAV到Windows资源管理器(含自启脚本)

本文详细介绍了如何使用开源工具Rclone替代RaiDrive,实现零广告、全免费的Alist WebDAV挂载方案。通过深入解析配置参数、提供完整的自启动解决方案和解决常见问题,帮助用户在Windows资源管理器中高效管理云存储,提升使用体验。

weixin_33709364的博客 631

7、Python高光谱分析工具(PyHAT)简介

Python高光谱分析工具(PyHAT)是一个开源、跨平台的Python库及图形用户界面,用于行星光谱数据的可视化与分析。它支持多种高光谱传感器数据,如火星勘测轨道飞行器的CRISM、月船1号的M3以及SELENE Kaguya SP点光谱仪,提供预处理、衍生产品生成、统计学习和机器学习分析功能。PyHAT基于Pandas和NumPy构建,兼容Jupyter和QGIS环境,旨在解决现有光谱分析方法缺乏开源实现、难以探索性分析和算法分散的问题。其模块化架构涵盖数据输入/输出、通用光谱变换、测绘与点观测工具及高

aa123的博客 137

BIO与NIO、AIO的区别(这个容易理解)

本文系统介绍了Java中的三种I/O模型:BIO(同步阻塞)、NIO(同步非阻塞)和AIO(异步非阻塞)。BIO每个连接对应一个线程,适合连接数少的场景;NIO通过多路复用实现单线程处理多个连接,适合高并发短连接;AIO由操作系统完成I/O操作后回调通知应用,适合大数据量长连接。文章分析了三种模型的工作原理、代码实现及适用场景,并对比了Reactor和Proactor模式。建议根据实际业务需求选择适合的I/O模型,短连接高并发选NIO,大数据量选AIO,简单场景可用BIO。

ywl470812087的博客 10万+

Sigrity Power DC Single-BoardPackage IR Drop Analysis模式进行单板压降仿真分析操作指导

如果需要单独对某个via设置参数,右侧选择Setup by padstack,下方下拉选择某个via,单独设置参数即可。举例:板厚1.6mm,内层1OZ(1.2mil,即0.03mm),铜皮宽度1mm,20度温升,允许通流I为2.5A。目的是模拟实际情况,via的孔壁电镀1mil,中间是空心的,让via不完全被填充金属成为实心via。Upper/lower Tolerance:上下公差,设置为5%,也就是压降允许的范围。电流密度计算公式:J=I/A(J为电流密度,I为电流,A为横截面积)

weixin_54787054的博客 695

BIO与NIO、AIO的区别

IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。 一、BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的...

IT界的一只菜鸟 1856

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

聊聊Java BIO(同步阻塞IO)、NIO(非阻塞IO)、AIO(异步IO)

Java中有阻塞IO、非阻塞IO。阻塞IO可以理解为“一个连接对应于一线程”。非阻塞IO可以理解为“一个请求(一个请求里面可能会有多个连接【长连接短连接】)对应于一线程”。 BIO Java中BIO也成为同步阻塞IO。 同步阻塞IO模式下,服务器实现模式为一个连接对应一个线程,即:有连接请求从客户端发起时,服务器端就需要创建一个线程进行处理,如果有大量连接时,服务器就需要创建大量线程进行处理。当然...

绕行的专栏 1173

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

JAVA BIO与NIO、AIO

NIO的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,所以所有的连接只需要一个线程就可以搞定,当这个线程中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。在NIO的处理方式中,当一个请求来的话,开启线程进行处理,可能会等待后端应用的资源(JDBC连接等),其实这个线程就被阻塞了,当并发上来的话,还是会有BIO一样的问题。且建立好的连接,在通讯过程中,是同步的。Blocking IO: 同步阻塞的编程方式。

m0_74301144的博客 852

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

BIO、NIO、AIO的区别

同步阻塞(blocking-IO)简称BIO 同步非阻塞(non-blocking-IO)简称NIO 异步非阻塞(asynchronous-non-blocking-IO)简称AIO BIO(同步阻塞I/O模式): 数据的读取写入必须阻塞在一个线程内等待其完成。这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。 NIO(同.

qianhuan_的博客 1369

BIO,NIO,AIO的区别

一、看图网上很多IO资料,对新手来说,越看越晕。根据自己的理解,总结对比了一下BIO、NIO、AIO。BIO:线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成。如下图:NIO(reactor模型):线程发起IO请求,立即返回;内核在做好IO操作的准备之后,通过调用注册的回调函数通知线程做IO操作,线程开始阻塞,直到操作完成。如下图:AIO(proactor模型...

RobertLab 3万+

Java的BIO,NIO与AIO

  Java中的IO操作可谓常见。在Java的IO体系中,常有些名词容易让人困惑不解。为此,先通俗地介绍下这些名词。   1 什么是同步?   2 什么是异步?   3 什么是阻塞?   4 什么是非阻塞?   5 什么是同步阻塞?   6 什么是同步非阻塞?   7 什么是异步阻塞?   8 什么是异步非阻塞?    我们先来弄明白什么是同步,异步,阻塞,非阻塞,只有这几个概念理解...

李章勇的博客 1506

java处理异步非阻塞请求_同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO

IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。一、BIO在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,...

weixin_42356145的博客 244

BIO、NIO、AIO 的区别

BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。 NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。 AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞IO,异步 IO 的操作基于事件和回调机制。 ...

m0_51660523的博客 757

记录一下同步和异步,BIO,NIO,AIO

同步和异步:同步和异步是针对应用程序和内核的交互而言的 同步指的是用户进程触发IO 操作并等待或者轮询的去查看IO 操作是否就绪。异步是指用户进程触发IO 操作以后便开始做自己的事情,而当IO 操作已经完成的时候会得到IO 完成的通知。 以银行取款为例: 同步 : 自己亲自持银行卡到银行取钱(使用同步 IO 时,Java 自己处理IO 读写); 异步 : 委托员工拿银行卡到银行取钱,然后给你(使用异步IO 时,Java 将 IO 读写委托给OS 处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS

liuzhe465的博客 233

异步非阻塞_聊聊Java BIO(同步阻塞IO)、NIO(非阻塞IO)、AIO(异步IO)

Java中有阻塞IO、非阻塞IO。阻塞IO可以理解为“一个连接对应于一线程”。非阻塞IO可以理解为“一个请求(一个请求里面可能会有多个连接【长连接短连接】)对应于一线程”。BIOJava中BIO也成为同步阻塞IO。同步阻塞IO模式下,服务器实现模式为一个连接对应一个线程,即:有连接请求从客户端发起时,服务器端就需要创建一个线程进行处理,如果有大量连接时,服务器就需要创建大量线程进行处理。当然可以通...

weixin_39597323的博客 153
上一篇: 万字攻略,详解腾讯面试(T1-T9)核心技术点,面试题整理
下一篇: 【干货分享】红黑树硬核讲解
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值