一篇文章,搞懂异步和多线程的区别

简介: 一篇文章,搞懂异步和多线程的区别

最近在研究Spring Boot中的异步处理,发现涉及到异步和多线程的很多知识点,就先写几篇关于异步与多线程的文章,带大一起回顾或学习一下相关的知识点。下面开始正文内容:


前言

在本文中,我们通过一些通俗易懂的方式来解释异步编程和多线程编程,然后再介绍一下它们之间的区别。


什么是异步编程

首先来看一下异步模型。在异步模型中,允许同一时间发生(处理)多个事件。程序调用一个耗时较长的功能(方法)时,它并不会阻塞程序的执行流程,程序会继续往下执行。当功能执行完毕时,程序能够获得执行完毕的消息或能够访问到执行的结果(如果有返回值或需要返回值时)。


下面通过一个示例来看一下同步和异步的区别。示例中程序通过网络获取两个文件,并对两个文件进行合并处理:


image.png上述示例,在异步系统当中的解决方案是开启一个额外的线程进行处理。第一个线程获取第一个文件,第二个线程获取第二个文件,第二个线程并不需要等待第一个线程执行完毕再执行。当两个线程都获得到对应的结果之后,再重新同步处理合并结果的操作。


再来看另外一个场景。单线程方法读取OS(操作系统)当中的文件并需要进行数学运算。而在异步系统中,程序发起读取OS中文件的请求,由于读取操作比较耗时,在等待读取文件时,程序会将控制器返回给CPU进行数学运算。


在异步编程中,通常会针对比较耗时的功能提供一个函数,函数的参数中包含一个额外的参数,用于回调。而这个函数往往称作回调函数。当比较耗时的功能执行完毕时,通过回调函数将结果返回。关于回调函数相关的知识可参考文章《两个经典例子让你彻底理解java回调机制》。


什么是多线程编程

多线程是指同时并发或并行执行多个指令(线程)。


在单核处理器上,多线程往往会给人程序是在并行执行的错觉。实际上,处理器是通过调度算法在多线程之间进行切换和调度。或者根据外部输入(中断)和线程的优先级的组合来进行线程的切换。


在多核处理器上,线程才是真正的并行运行。多个处理器同时执行多个线程,以达到更加高效的处理。


一个简单的示例就是:开启两个浏览器窗口同时下载两个文件。每个窗口都使用一个新的线程去下载文件,它们之间并不需要谁等待谁完成,而是并行进行下载。


下图展示了并发执行多线程应用程序的流程:


image.png异步与多线程的区别

通过上面的介绍,我们可以看出多线程都是关于功能的并发执行。而异步编程是关于函数之间的非阻塞执行,我们可以将异步应用于单线程或多线程当中。


因此,多线程只是异步编程的一种实现形式。


比如,你和你的朋友决定一起做一顿午餐。“异步”就是你对朋友说:“你去商店买意大利面,回来的时候告诉我一声,然后一起做午餐。在你买意大利面的同时,我去准备番茄酱和饮料。”


而“线程”是:“你烧水,我加热番茄酱。当水烧开了,告诉我,我把意大利放进去。当番茄酱热了,你可以把奶酪添加进去。当两者都完成了,就可以坐下来一起吃晚餐。”在线程的示例中,我们可以看到“When,Do”的事件顺序,而这些顺序代表着每个人(线程)的指令集集合的顺序。


上述示例可以看出,多线程是与具体的执行者相关的,而异步是与任务相关的。


多线程是程序设计的逻辑层概念,它是进程中并发运行的一段代码,可以实现线程间的切换执行。


异步和同步是相对的,异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。


多线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其它的事情。


所以本质上,异步和多线程并不是一个同等关系,异步是最终目的,多线程只是实现异步的一种手段。


如何选择

面对多线程和异步,我们该如何选择呢?其实,通常情况下选择的依据是主要取决于性能。


那么,同步/异步与单线程/多线程之间的所有组合,哪种模型表现更好?


简而言之,对于具有大量I/O操作和不同计算的大规模应用程序,使用异步多线程有利于充分利用计算资源,并且能够照顾到非阻塞函数。这也是所有操作系统所采用的线程模型。


编写异步操作的复杂程度较高,程序主要使用回调方式进行处理,与正常的思维方式有些出入,而且难以调试。而多线程的使用(滥用)会给系统带来上下文切换的额外负担,并且线程间的共享变量可能造成死锁。


因此在实现这两种模式时,往往需要处理资源竞争、死锁、共享资源和回调事件等问题。


小结

在本文中,我们讲解了异步编程和多线程编程的定义,然后是它们之间的区别。而本文中的所有术语和概念均与具体技术实现无关。后面我们会继续讲解多线程与异步相关的其他知识点,比如异步调用与回调等。


目录
相关文章
|
1月前
|
编解码 数据安全/隐私保护 计算机视觉
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
如何使用OpenCV进行同步和异步操作来打开海康摄像头,并提供了相关的代码示例。
72 1
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
|
1月前
|
Dubbo Java 应用服务中间件
剖析Tomcat线程池与JDK线程池的区别和联系!
剖析Tomcat线程池与JDK线程池的区别和联系!
103 0
剖析Tomcat线程池与JDK线程池的区别和联系!
|
27天前
|
缓存 算法 Java
Java 中线程和纤程Fiber的区别是什么?
【10月更文挑战第14天】
59 0
|
2月前
|
NoSQL 网络协议 Unix
1)Redis 属于单线程还是多线程?不同版本之间有什么区别?
1)Redis 属于单线程还是多线程?不同版本之间有什么区别?
64 1
|
1月前
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
|
1月前
|
网络协议 安全 Java
难懂,误点!将多线程技术应用于Python的异步事件循环
难懂,误点!将多线程技术应用于Python的异步事件循环
61 0
|
2月前
|
设计模式 缓存 Java
谷粒商城笔记+踩坑(14)——异步和线程池
初始化线程的4种方式、线程池详解、异步编排 CompletableFuture
谷粒商城笔记+踩坑(14)——异步和线程池
WK
|
2月前
|
并行计算 调度 Python
GIL和线程之间的区别是什么
全局解释器锁(GIL)与线程在Python中具有不同角色。GIL作为CPython中的互斥锁,确保同一时间只有一个线程执行Python字节码,简化内存管理但限制多线程并行性;线程则是程序执行的最小单位,允许多个任务并发运行。GIL影响整个解释器,使多线程串行化;线程则代表独立执行流,受GIL制约。GIL在计算密集型任务中成为瓶颈,但在I/O密集型任务中多线程仍可提升性能。理解两者差异有助于优化多线程应用。
WK
30 0
|
3月前
|
消息中间件 资源调度 调度
进程与线程的区别
【8月更文挑战第24天】
36 0
|
3月前
|
消息中间件 安全 Java
Java 中的线程与进程之区别
【8月更文挑战第22天】
92 0