万事从最基本的开始。

要想完全掌握 NIO,并不是掌握上面文章(【死磕NIO】— NIO基础详解)中的三大组件就可以了,我们还需要掌握一些基本概念,如什么是 IO,5 种IO模型的区别,什么是阻塞&非阻塞等等,只有掌握了这些基本概念,我们对NIO才能理解得更加得心应手。

这篇文章我们就从阻塞&非阻塞,同步&异步说起。

同步与异步

什么是同步与异步呢?百度百科是这样定义的:

同步指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系。

异步与同步相对(这解释让我无言相对)

所以,我们需要明确的是同步与异步针对的是两个或者两个以上的事物

对于同步而言,一个任务(调用者)的完成需要依赖另一个人任务(被调用者)的完成,只有等待被依赖的任务完成,依赖的任务才会继续进行,两者步调保持一致。

异步呢?任务与它依赖的任务没有必然的联系,它不需要等待它依赖的任务完成,它只需要向依赖任务发起调用即可,告诉它你可以干活了,至于你啥时候干完跟我没关系。

所以说,同步和异步的本质区别就在于调用者与被调用者之间结果消息通知机制的不同

  • 同步:调用者需要一直主动等待被调用者的结果。
  • 异步:调用者调用被调用者后,调用者不会立刻得到结果,在调用者发起调用后,被调用者通过状态、通知或通过回调函数,让调用者知道结果

所以,同步和异步一个是主动等待结果,一个是被动知道结果。

举一个简单的例子:买奶茶,我们有两种方式拿到我们买的奶茶

  • 选择排队等待。这种方式就是同步等待消息通知了,我们需要一直在吧台面前等着我们的奶茶
  • 扫码。这种方式,你可以不停地看手机排号是否到你了(状态),也可以在那里玩手机等着服务员喊 88 号,奶茶好了(通知)。

上面提到异步调用可以通过状态、通知或者回调函数来告知调用者。

  • 状态:调用者需要每隔一段向被调用者发起一个状态查询请求。这种方式效率较为低下。一般我们在调用支付接口的时候,如果服务方告知支付状态未知,则我们需要每隔一段时间去查询该笔订单的支付状态。虽然效率较为低下,但是靠谱。
  • 通知:这种方式,调用者不需要做额外的工作,他只需要等被调用者把结果告诉调用者即可。但是这种方式也有点不是那么靠谱,它到底啥时候调用,如果不调用怎么办呢?这些都是我们需要考虑的问题。
  • 回调函数:和通知机制差不多。

阻塞与非阻塞

上面解释了什么是同步与异步,那什么是阻塞与非阻塞呢?

所谓阻塞,就是有障碍而不能通行,无法畅通。

所以,阻塞就是调用结果返回之前,该线程会被一直挂起,一直等待结果,不能继续,函数只有在得到结果之后才会返回

可能有小伙伴会将阻塞与同步等同起来,因为他们都是因为等待执行结果而停滞不前,其实两者还是有区别的:

  • 同步,针对的是两个进程,一个进程(调用者)因为等待另一个进程(被调用者)的执行结果而停滞不前。而阻塞则是针对一个,它是因为自己本身因等待当前线程中某个执行结果而停滞不前的。
  • 对于同步来说,当前线程还是处于激活状态,只是从逻辑(感官)来说它是停滞不前的,当前线程可能还在处理其他事情。而阻塞则不同,当前线程是被挂起了,直接让出了 CPU。

非阻塞则与阻塞概念相对,指在不能立即得到执行结果之前,该函数不会阻碍当前线程执行,而是会立即返回

还是上面那个买奶茶的例子,不论是排队在那里等奶茶还是扫码在哪里等奶茶,只要在等奶茶的过程中你没有做其他事情都是阻塞。如果你在等的过程跟你女朋友聊天(假如你有女朋友的话)或者在玩手机,那么就是非阻塞,因为没有因等待奶茶这件事一直耗着,而是一边等一边干其他的事情。

同步&异步、阻塞&非阻塞

同步&异步与阻塞&非阻塞两两组合,分别为同步阻塞,同步非阻塞异步阻塞异步非阻塞。以上面等奶茶的例子为例。

同步阻塞

你在排队等奶茶的过程中,什么事情都不能做,只能干等着。就问你无聊不无聊,尴尬不尴尬。效率最为低下

同步非阻塞

你在排队等奶茶的过程中,可以干其他事情,比如刷抖音,玩一把王者荣耀,但是你需要不断地看奶茶是否已经到你,你势必会分心导致输掉王者荣耀,成为一个坑货。注意排队等奶茶,玩王者荣耀是两件事情,你需要两件事情来回不断地切换,效率也不见得高到哪里去

异步阻塞

你扫码拿号后,你不用在那里排队干等,你只需要等候服务员告诉你奶茶做好了去拿就可以了,但是在这个等的过程中,你啥事都不能干,只能干等着。很显然你已经被阻塞在这个等待服务员告诉你奶茶做好了的事情(消息通知)上面了。我们要注意是,并不是说异步就不能阻塞了,异步也是可以阻塞的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞了

异步非阻塞

你扫码拿号后,直接去边上玩王者荣耀了,中途你专心玩的王者荣耀,不需要分心去关注你的奶茶是否做好了,你只需要在那里等服务员告诉你奶茶做好了(消息通知)去拿就可以了。效率最高

参考资料

【死磕NIO】— 阻塞、非阻塞、同步、异步,傻傻分不清楚的更多相关文章

  1. 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?

    通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...

  2. 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor

    开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...

  3. JAVA 中BIO,NIO,AIO的理解以及 同步 异步 阻塞 非阻塞

    在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步 ...

  4. 【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)

    常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...

  5. 【转载】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)

    原文链接:https://www.cnblogs.com/lixinjie/p/10811219.html 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使 ...

  6. 同步/异步/阻塞/非阻塞/BIO/NIO/AIO

    转摘自:https://www.cnblogs.com/lixinjie/p/a-post-about-io-clearly.html 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HT ...

  7. 迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)

    常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...

  8. 同步/异步/阻塞/非阻塞/BIO/NIO/AIO各种情况介绍

    常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...

  9. 进程&线程 同步异步&阻塞非阻塞

    2015-08-19 15:23:38 周三 线程 线程安全 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码 线程安全问题都是由全局变量及静态变量引起的 若每个线程中对 ...

随机推荐

  1. Linux从头学07:中断那么重要,它的本质到底是什么?

    作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...

  2. SpringBoot开发九-生成验证码

    需求介绍-生成验证码 先生成随机字符串然后利用Kaptcha API生成验证图片 代码实现 先在pom.xml引入 <dependency> <groupId>com.gith ...

  3. VRRP的基本配置

    一.实验拓扑 二.实验编址 三.实验步骤: 1.设置PC的IP等信息 2.启动设备(全选) 3.设置路由器端口ip 4. 配置ospf网络 查看: 5.配置VRRP协议 配置完成后查看: 6.验证主备 ...

  4. 【工作篇】再次熟悉 SpringMVC 参数绑定

    前言 主要现在项目中使用的参数绑定五花八门的,搞得很头大,例如有些用字符串接收日期,用字符串接受数组等等,完全没有利用好 SpringMVC 的优势,这里自己也总结一下,免得到时又要百度谷歌查找. 以 ...

  5. 题解 Medium Counting

    传送门 又是神仙DP 发现如果只有两个串就很好做了 于是这个神仙DP定义就从这里下手:令 $dp[p][c][l][r] 表示在 \([s_l, s_r]\) 这段字符串中,考虑从第 \(p\) 个位 ...

  6. 安装 iperf和服务器之间测速

    安装 # https://downloads.es.net/pub/iperf/iperf-3.1.3.tar.gz wget https://iperf.fr/download/source/ipe ...

  7. 【SpringMVC】@RequestMapping注解

    @RequestMapping注解的源码 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNT ...

  8. 如何选择Spring cloud和 Spring Boot对应的版本

    如何选择Spring cloud和 Spring Boot对应的版本 首先,我们进入Spring Cloud官网,查询Spring cloud的版本和对应的Spring Boot版本 打开Spring ...

  9. wpf 的style

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x ...

  10. udphdr结构

    udphdr结构包含在/usr/src/linux/include/linux/udp.h 1 struct udphdr { 2 __u16 source; 3 __u16 dest; 4 __u1 ...