万事从最基本的开始。

要想完全掌握 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. 10 个超棒的 JavaScript 简写技巧

    今天我要分享的是10个超棒的JavaScript简写方法,可以加快开发速度,让你的开发工作事半功倍哦. 开始吧! 1. 合并数组 普通写法: 我们通常使用Array中的concat()方法合并两个数组 ...

  2. 手工设置Eclipse文本编辑器的配色

    Eclipse中不同的文件都有自己专门的编辑器配色设置,下面分别说明. 文本编辑器的背景色: Window->Preferences-> General->Editors->T ...

  3. Django3使用WebSocket实现WebShell

    前言 最近工作中需要开发前端操作远程虚拟机的功能,简称WebShell. 基于当前的技术栈为react+django,调研了一会发现大部分的后端实现都是django+channels来实现websoc ...

  4. NOIP 模拟 $20\; \rm z$

    题解 很考验思维的一道题 对于不同的任务点,发现如果 \(x_{i-1}<x_i<x_{i+1}\) 或 \(x_{i-1}>x_i>x_{i+1}\) 那么 \(x_i\) ...

  5. 《深入理解java虚拟机》第3版笔记3

    第3章 垃圾收集器与内存分配策略 可达性分析算法 在Java技术体系里面,固定可作为GC Roots的对象包括以下几种: 在虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使 ...

  6. Flink 保证ExactlyOnce

    Flink 保证 ExactlyOnce 1.使用执行ExactlyOnce 的数据源,比如 kafka 2.使用FlinkConsumer,开启CheckPointing,偏移量会保存通过Check ...

  7. Nginx 极简入门教程!(转)

    基本介绍 Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务. Nginx 是由伊戈尔·赛索耶夫为俄罗斯访问量第二的 Rambler.r ...

  8. Caffe 快速入门笔记

    官网:http://caffe.berkeleyvision.org/ 其中包含Notebook Example方便入门学习 只是使用她的库还是比较简单,其难点在于: 安装 源码 训练好的模型,用于迁 ...

  9. 根据短链生成二维码并上传七牛云(Java)

    通过短链生成二维码并上传七牛云(Java) 前言 网上这种帖子其实也是很多,大部分搜出来的是CSDN的,然后点进去一看都几乎一样:所以这次给个自己实践的例子记录. 这次也是通过搜索得到的一部分能实现这 ...

  10. layui的CRUD案列

    用layui来实现一个简单的二级权限和增删改查案列 利用layui提供的组件(table , layer , form,tree)来进行开发 写一个简单的登录界面   根据用户的ID来 获取用户所对应 ...