异步执行和同步执行之间的区别是什么?
当前回答
简而言之,同步指的是两个或多个进程的起点和终点,而不是它们的执行。在本例中,进程A的端点与进程B的起点同步:
SYNCHRONOUS |--------A--------| |--------B--------|
另一方面,异步进程的起点和终点不同步:
ASYNCHRONOUS |--------A--------| |--------B--------|
在进程A与进程B重叠的地方,它们是并发或同步运行的(字典定义),因此造成了混淆。
更新:Charles Bretana改进了他的答案,所以这个答案现在只是一个简单的(可能过于简化了)助记符。
其他回答
同步执行意味着在单个系列中执行。A - C > B - > - > D。如果您正在调用这些例程,则A将运行,然后结束,然后B将开始,然后结束,然后C将开始,等等。
使用异步执行,你开始一个例程,并让它在后台运行,同时你开始下一个例程,然后在某个时候,说“等待这个完成”。更像是:
开始A->B->C->D->等待A完成
这样做的好处是,当A仍在运行时(在后台,在一个单独的线程上),您可以执行B、C和或D,因此您可以更好地利用资源,减少“挂起”或“等待”。
同步/异步与多线程无关。
同步或同步意味着“连接”,或在某种程度上“依赖”。换句话说,两个同步任务必须彼此知道,并且一个任务必须以依赖于另一个任务的某种方式执行,例如等待开始,直到另一个任务完成。 异步意味着它们是完全独立的,任何一方都不能以任何方式考虑另一方,无论是在初始化还是执行中。
同步(一个线程):
1 thread -> |<---A---->||<----B---------->||<------C----->|
同步(多线程):
thread A -> |<---A---->|
\
thread B ------------> ->|<----B---------->|
\
thread C ----------------------------------> ->|<------C----->|
异步(一个线程):
A-Start ------------------------------------------ A-End
| B-Start -----------------------------------------|--- B-End
| | C-Start ------------------- C-End | |
| | | | | |
V V V V V V
1 thread->|<-A-|<--B---|<-C-|-A-|-C-|--A--|-B-|--C-->|---A---->|--B-->|
异步(多线程):
thread A -> |<---A---->|
thread B -----> |<----B---------->|
thread C ---------> |<------C--------->|
任务A, B, C的起始和结束点用<,>字符表示。 CPU时间片用竖条|表示
从技术上讲,同步/异步的概念实际上与线程没有任何关系。虽然,在一般情况下,在同一个线程上运行异步任务是不寻常的,但这是可能的(参见下面的例子),并且在不同的线程上同步执行两个或多个任务是很常见的……不,同步/异步的概念只与是否可以在另一个(第一个)任务完成之前启动第二个或后续任务有关,或者它是否必须等待。仅此而已。任务执行在哪个线程(或多个线程)、进程、cpu,甚至是什么硬件上都无关紧要。事实上,为了说明这一点,我编辑了图表来显示这一点。
异步的例子:
在解决许多工程问题时,软件被设计成将整个问题分解成多个单独的任务,然后异步地执行它们。求矩阵的逆,或者有限元素分析问题,都是很好的例子。在计算中,对列表排序就是一个例子。例如,快速排序例程将列表分成两个列表,并对每个列表执行快速排序,递归地调用自身(快速排序)。在上面的两个例子中,这两个任务都可以(而且经常是)异步执行。它们不需要在单独的线程上。即使是只有一个CPU和一个执行线程的机器,也可以在第一个任务完成之前开始第二个任务的处理。唯一的标准是,一个任务的结果不需要作为另一个任务的输入。只要任务的开始时间和结束时间重叠(只有在两个任务的输出都不需要作为另一个任务的输入时才有可能),它们就是异步执行的,不管使用了多少线程。
同步的例子:
由多个任务组成的任何进程,这些任务必须按顺序执行,但其中一个任务必须在另一台机器上执行(获取和/或更新数据,从金融服务获取股票报价,等等)。如果它在单独的机器上,那么它就在单独的线程上,无论是同步的还是异步的。
我创建了一个动图来解释这一点,希望能有所帮助: 看,第3行是异步的,其他是同步的。 在行3之前的所有行都应该等到行完成它的工作,但因为行3是异步的,下一行(行4),不要等待行3,但行5应该等待行4完成它的工作,行6应该等待行5和7的6,因为行4,5,6,7不是异步的。
同步的不同英文定义在这里
协调;结合。
我认为这比“同时发生”的定义更好。这也是一个定义,但我不认为它适合计算机科学中使用的方式。
因此异步任务不与其他任务协同,而同步任务与其他任务协同,因此一个任务在另一个任务开始之前完成。
如何实现这一点是另一个问题。
同步与异步
同步和异步操作是关于下一个任务相对于当前任务的执行顺序。
让我们看一个例子,Task 2是当前任务,Task 3是下一个任务。Task是堆栈(方法帧)中的原子操作方法调用。
同步
意味着任务将逐个执行。当前任务完成后才会启动下一个任务。任务2完成后才启动任务3。
单线程+同步-顺序
通常执行。
伪代码:
main() {
task1()
task2()
task3()
}
多线程+同步-并行
屏蔽。
阻塞意味着线程只是在等待(尽管它可以做一些有用的事情)。例如:Java ExecutorService[About] and Future[About])伪代码:
main() {
task1()
Future future = ExecutorService.submit(task2())
future.get() //<- blocked operation
task3()
}
异步
暗示任务立即返回控制,并承诺执行代码,稍后通知结果(例如。回调功能)。即使任务2没有完成,任务3也会执行。异步回调,完成处理程序
单线程+异步-并发
使用回调队列(消息队列)和事件循环(运行循环,循环器)。事件循环检查线程堆栈是否为空,如果为真,则将第一个项目从回调队列推入线程堆栈,并再次重复这些步骤。简单的例子是按钮点击,发布事件…
伪代码:
main() {
task1()
ThreadMain.handler.post(task2());
task3()
}
多线程+异步-并发和并行
非阻塞。
例如,当你需要在不阻塞的情况下在另一个线程上进行一些计算。伪代码:
main() {
task1()
new Thread(task2()).start();
//or
Future future = ExecutorService.submit(task2())
task3()
}
你可以使用阻塞方法get()或通过循环使用异步回调来使用Task 2的结果。
例如,在移动世界中,我们有UI/主线程,我们需要下载一些东西,我们有几个选择:
同步块-阻塞UI线程并等待下载完成。UI没有响应。 异步回调-创建一个新的线程,使用异步回调来更新UI(不可能从非UI线程访问UI)。回调地狱。 async coroutine[关于]-带有同步语法的异步任务。它允许将下载任务(挂起功能)与UI任务混合。
[iOS同步/异步],[Android同步/异步]
[并行vs并行]