概述
先来看看异步、同步、阻塞和非阻塞的区别。
同步和异步
同步和异步是针对通信方式而言的,表示调用方和服务方之间是同步通信还是异步通信。同步通信是指,调用方调用服务方的方法之后,调用方会等待服务方返回结果。异步通信是指,调用方调用服务方的方法之后,就直接返回了,不会继续等待,结果一般是通过状态和消息来告诉调用方,或者调用方代理执行回调函数来处理结果。
阻塞和非阻塞
阻塞和非阻塞是针对调用方的状态而言的,表示调用方调用了方法之后所处的状态。阻塞调用在结果返回之前,调用方的线程会被挂起。非阻塞调用在结果返回之前,调用方线程不会阻塞,可以做其他事情。
通信方式与阻塞方式的组合
如果将通信方式和阻塞方式结合起来,则有四种组合。
-
同步阻塞 这是一种后端RD调用远程RPC方法时最常用的方式。调用方在调用RPC方法之后,调用方线程会同步等待,直到PRC方法返回结果。这也是后端RD最习惯使用的方式。
-
异步非阻塞 这是后端RD比较习惯使用的一种RPC方法调用方式。调用方在调用RPC方法之后,调用方线程不会同步等待结果,而是继续执行接下来的业务逻辑。例如,使用异步的方式调用RPC方法,不等待返回结果;或者通过消息代理发送消息。
-
同步非阻塞 这种方式体现在调用方不会阻塞,可以做其他的事情;同时,通过轮训来查询和等待结果。该方式要求服务端提供查询结果的方法。linux提供的IO多路复用函数select、poll和epool就是采用的同步非阻塞方式。
-
异步阻塞 异步阻塞的方式看起来很奇怪,调用方调用服务方的方法之后,调用方线程会被挂起;结果不会同步返回。这种方式的一种使用场景是:服务方只提供了异步的方法,调用方依赖于服务方提供的结果,只能阻塞等待异步的结果。
结合实际的情况想想,为了提高做事情的效率,人们常常采用异步非阻塞的方式。例如,A和B要去另一个城市旅游,如果按照同步的方式,流程是这样的:
而实际的情况是这样的(异步的方式):
本人认为,异步的方式才是人们在实际生活中做事情的常用方式,而不是采用同步的方式。RD习惯于同步阻塞的业务逻辑,这样是很简单轻松,但是牺牲了性能;采用异步的方式,在业务逻辑上并不会增加很多困难,毕竟异步的方式才是人们实际生活中所习惯的。
通过异步的方式,在很多场景下,可以提高程序运行效率。配合声明式的编程方式,可以让逻辑更加清晰,维护起来更轻松。
接下来,我们将学习异步编程的各种方式。
异步与并发的关系
异步非阻塞的方式下,调用方不会等待服务方返回结果,会继续执行接下来的业务逻辑;服务方会执行一部分逻辑。可想而知,异步得依赖于多个线程或者多个进程,因为有两个业务逻辑得同时执行。在异步PRC方法的情况下,体现为多个进程;在同一个JVM中,体现为多个线程。
2 单个JVM中的异步的实现方式
异步是一种通信方式,实现它的技术有很多:
- 显示使用线程池方式
- 基于JDK中的Future
- 基于Java 8中的CompletableFuture
- Spring封装的异步方法执行注解@Async
- 反应式编程
- 线程间消息传递库-Disruptor
3 总结
这里,我们介绍了同步和异步的区别,阻塞和非阻塞的区别,简单介绍了异步编程常见的实现方式。本系列所介绍的异步编程实现方式主要用于单个JVM中用来实现异步,并没有涉及服务化情况下的异步。服务化的情况下的异步方式还包括:
- 异步的、基于事件驱动的网络通信框架-Netty
- RPC框架一般会提供异步通信的方式
- 异步的、基于消息驱动的框架-Akka
- 分布式的消息框架-Kafka
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下