理解阻塞、非阻塞与同步、异步的区别

简介: 理解阻塞、非阻塞与同步、异步的区别

考虑一千次,不如去做一次;犹豫一万次,不如实践一次;华丽的跌倒,胜过无谓的彷徨,将来的你,一定会感谢现在奋斗的你。

IO编程

IO在计算机中,指input/Output,即输入和输出。


比如你打开浏览器,访问微博首页,浏览器这个程序就需要通过网络IO获取微博的网页。浏览器首先会发送数据给微博服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后微博服务器把网页发过来,这个动作是从外面接收数据,叫Input。所以,通常,程序完成IO操作会有Input和Output两个数据流。当然也有只用一个的情况,比如,从磁盘读取文件到内存,就只有Input操作,反过来,把数据写到磁盘文件里,就只是一个Output操作。


IO编程中,Stream(流)是一个很重要的概念,可以把流想象成一个水管,数据就是水管里的水,但是只能单向流动。Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。对于浏览网页来说,浏览器和微博服务器之间至少需要建立两根水管,才可以既能发数据,又能收数据。

image.png

阻塞和非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。


阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。


比如餐馆的服务员为用户点菜,当有用户点菜后,服务员将菜单给后台的厨师,此时有2种方式:


第一种: 服务员什么也不干就在出菜的窗口一直等待,直到厨师讲菜做好送来,然后服务员再将菜送到用户手中

第二种: 服务员先去做其他事情,然后过一会来窗口询问菜是否做好。没做好过一段时间又来询问

以上两种方式,第一种就是阻塞的,另外一种是非阻塞的。

同步和异步

同步和异步关注的是消息通信机制。


所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。


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


对于同步的事件,你只能以阻塞的方式去做。而对于异步的事件,阻塞和非阻塞都是可以的。非阻塞又有两种方式:主动查询和被动接收消息。被动不意味着一定不好,在这里它恰恰是效率更高的,因为在主动查询里绝大部分的查询是在做无用功。对于带通知的异步事件,两者皆可。而对于不带通知的,则只能用主动查询。


但是对于非阻塞和异步的概念有点混淆,非阻塞只是意味着方法调用不阻塞,就是说作为服务员的你不用一直在窗口等,非阻塞的逻辑是"等可以读(写)了告诉你",但是完成读(写)工作的还是调用者(线程)服务员的你等菜到窗口了还是要你亲自去拿。而异步意味这你可以不用亲自去做读(写)这件事,你的工作让别人(别的线程)来做,你只需要发起调用,别人把工作做完以后,或许再通知你,它的逻辑是“我做完了 告诉/不告诉 你”,他和非阻塞的区别在于一个是"已经做完"另一个是"可以去做"。

老王烧水的例子

网上流传的一个经典的老王烧水的故事(网友真TM有才):


出场人物:老王,水壶两把(普通水壶,简称水壶;烧开后会响的水壶,简称响水壶)。


老王想了想,有好几种等待方式:


1.老王用水壶烧水,并且站在那里,不管水开没开,每隔一定时间看看水开了没。——同步阻塞


老王想了想,这种方法不够聪明。


2.老王还是用水壶烧水,不再傻傻的站在那里看水开,跑去卧室上网,但是还是会每隔一段时间过来看看水开了没有,水没有开就走人。——同步非阻塞(轮询)


老王想了想,现在的方法聪明了些,但是还是不够好。


3.老王这次使用高大上的响水壶来烧水,还是站在那里,但是不会再每隔一段时间去看水开,而是等水开了,水壶会自动的通知他。——异步阻塞


老王想了想,既然水壶可以通知我,那我为什么还要傻傻的站在那里等呢,嗯,得换个方法。


4.老王还是使用响水壶烧水,跑到卧室上网去,等着响水壶自己把水烧开了以后通知他。——异步非阻塞


老王豁然,这下感觉轻松了很多。


同步和异步


同步就是烧开水,需要自己去轮询(每隔一段时间去看看水开了没),异步就是水开了,然后水壶会通知你水已经开了,你可以回来处理这些开水了。

同步和异步是相对于操作结果来说,会不会等待结果返回。


阻塞和非阻塞


阻塞就是说在烧水的过程中,你不可以去干其他的事情,非阻塞就是在同样的情况下,可以同时去干其他的事情。阻塞和非阻塞是相对于线程是否被阻塞。


同步与阻塞、非阻塞与异步这一块有点难以理解。详细可以查看:

怎样理解阻塞非阻塞与同步异步的区别?


有兴趣的老爷,可以关注我的公众号【一起收破烂】,回复【006】获取2021最新java面试资料以及简历模型120套哦~


相关文章
|
API iOS开发
彻底搞懂同步与异步,阻塞/非阻塞
彻底搞懂同步与异步,阻塞/非阻塞
3088 0
|
存储 算法 Linux
【Linux 应用开发 共享内存】深入理解和实践 ftruncate:共享内存的有效管理
【Linux 应用开发 共享内存】深入理解和实践 ftruncate:共享内存的有效管理
493 5
|
机器学习/深度学习 网络协议 Java
聊聊 wireshark 的重传包和重复包(Duplicate Packets or TCP Retransmissions?)
聊聊 wireshark 的重传包和重复包(Duplicate Packets or TCP Retransmissions?)
|
4月前
|
算法 Shell 定位技术
在Docker环境下搭建openvslam/orb_slam3的步骤和问题总结
总的来说,搭建openvslam或orb_slam3的过程需要一些耐心和技术知识,但只要你遵循上述步骤,并且在遇到问题时进行适当的调试,你应该能够成功搭建并运行openvslam或orb_slam3。
215 11
|
8月前
|
存储 搜索推荐 关系型数据库
ElasticSearch 详解
ElasticSearch 是一款优秀的开源搜索引擎,适用于大数据场景下的高效检索与分析。其分布式架构、实时搜索和灵活的数据分析功能使其能处理 PB 级数据量。相比 Solr,ES 在实时性、分布式架构和文档处理上更具优势。核心概念包括索引、文档、分片和副本等。ES 使用倒排索引实现快速搜索,区别于正向索引。与关系型数据库相比,ES 更适合非结构化数据和全文搜索。总结来说,ES 在电商搜索、日志分析等领域有广泛应用,未来有望带来更多创新。
397 19
【bug记录】旋转链表与力扣报错:member access within null pointer of type ‘struct ListNode‘
【bug记录】旋转链表与力扣报错:member access within null pointer of type ‘struct ListNode‘
204 0
|
11月前
|
人工智能 自然语言处理 Java
我和我的通义灵码
本文介绍了阿里云的AI代码助手——通义灵码,从个人版和企业版两个方面详细阐述了其功能和使用方法。作者作为一名Java开发工程师,分享了自己使用通义灵码的经验,包括代码生成、智能问答等功能,以及如何通过@workspace、@terminal和#team docs等命令提高开发效率。文章还提到了企业版的特色功能,如企业知识库的配置和代码优化,展示了通义灵码如何帮助企业提高代码质量和开发效率。
|
11月前
|
存储 JavaScript 数据库
ToB项目身份认证AD集成(一):基于目录的用户管理、LDAP和Active Directory简述
本文介绍了基于目录的用户管理及其在企业中的应用,重点解析了LDAP协议和Active Directory服务的概念、关系及差异。通过具体的账号密码认证时序图,展示了利用LDAP协议与AD域进行用户认证的过程。总结了目录服务在现代网络环境中的重要性,并预告了后续的深入文章。
427 2
|
设计模式 Java 编译器
我们可以在 switch case 中使用 String 吗?
【8月更文挑战第21天】
723 0
|
存储 弹性计算 人工智能
【云故事探索】NO.2:引领汽车行业智能进化,看朴数智能如何重塑数字营销版图
朴数智能,一家专注AI自动化的科技公司,借助阿里云的云服务,尤其是云手机和桌面云技术,成功实现业务的快速增长和数字化转型。在阿里云的稳定性和高效支持下,朴数智能应对业务弹性需求,提升了运营效率。双方在“客户第一”的理念上达成共识,形成紧密合作,共同面对数字化时代的挑战,共创未来。阿里云不仅是技术提供者,更是朴数智能成长的伙伴,一同解锁了数字化转型新篇章。
【云故事探索】NO.2:引领汽车行业智能进化,看朴数智能如何重塑数字营销版图

热门文章

最新文章