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

同步与异步、阻塞与非阻塞常被对比讨论,它们分别从不同角度描述程序的执行特性。

同步和异步:从消息通信机制角度描述

  • 同步:强调调用者与被调用者之间的协调。在同步操作里,调用者发起调用后,会主动等待被调用者的响应结果,只有拿到结果,调用者才会继续后续操作。这就像是你打电话向朋友询问一个问题,你会一直拿着电话等朋友把答案说完,在这期间不做其他事情,程序的执行流程是顺序、连贯的,各个操作按部就班地进行。例如在传统的数据库查询中,执行查询语句后,程序会等待数据库返回查询结果,然后再继续后续处理。

  • 异步:调用者发起调用后,不会等待被调用者的结果,而是继续执行自身后续的任务。被调用者完成任务后,会通过特定的方式(如回调函数、事件通知)告知调用者。好比你给朋友发了条短信问问题,发完短信后你可以去做别的事,等朋友回复短信时你再处理。异步机制使得程序能够在等待某个操作完成的同时去处理其他任务,提高了系统的并发处理能力和整体效率。例如在前端开发中,使用 XMLHttpRequest进行异步数据请求,在请求发送后,页面不会被阻塞,可以继续响应用户的其他操作,当请求完成后,通过回调函数来处理返回的数据。

阻塞和非阻塞:从线程状态角度描述

  • 阻塞:主要关注线程在执行过程中的状态。当线程执行到某个操作时,如果该操作无法立即完成,线程会被挂起,进入阻塞状态,在这个状态下线程不占用 CPU 资源,但也不能执行其他任务,直到阻塞条件解除。就像你在排队买票,队伍不动你就只能干等着,什么别的事都做不了。例如在 Java 中,使用 FileInputStream 的 read 方法从文件中读取数据时,如果文件数据还未准备好,线程就会阻塞在该方法调用处。

  • 非阻塞:线程执行操作时,如果操作不能立即完成,线程不会被挂起,而是会立即返回,然后可以继续执行其他任务。线程会通过不断轮询或者其他方式来检查操作是否完成。这类似于你去餐厅点餐,服务员告诉你餐还没做好,你可以先去逛逛商场,过一会儿再回来看看餐好了没。在 Java 的 NIO 编程中,使用 Selector 可以实现非阻塞的 I/O 操作,线程可以同时处理多个通道的读写请求,不会因为某个通道没有数据而阻塞。

同步和阻塞、异步和非阻塞的关系

虽然同步与阻塞、异步与非阻塞在很多场景下有相似的表现,但它们并不完全等同。

同步操作可能是阻塞的,比如上面提到的传统数据库查询,既同步又阻塞;但同步操作也可以通过一些机制实现非阻塞,例如在一些基于事件驱动的同步模型中,通过不断轮询来检查操作是否完成,在等待过程中线程可以做其他事情。异步操作通常是非阻塞的,因为调用者在发起调用后可以继续执行其他任务,但也存在异步阻塞的情况,比如调用异步操作后,调用者主动等待异步任务的结果,这就相当于把异步操作变成了阻塞的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值