异步执行和同步执行之间的区别是什么?
当前回答
我认为这是一个有点迂回的解释,但它仍然澄清了使用现实生活中的例子。
小例子:
让我们假设播放音频包含三个步骤:
从硬盘中获取压缩的歌曲 解压音频。 播放未压缩的音频。
如果你的音频播放器为每首歌依次执行步骤1、2、3,那么它就是同步的。你必须等待一段时间才能听到这首歌,直到这首歌真正被提取和解压。
如果你的音频播放器独立执行第1、2、3步,那么它就是异步的。ie。 当播放音频1(步骤3)时,如果它并行地从硬盘中获取音频3(步骤1),并且并行地解压音频2。(第二步) 你最终会听到这首歌,而不需要等待太多的取回和解压。
其他回答
简而言之,同步指的是两个或多个进程的起点和终点,而不是它们的执行。在本例中,进程A的端点与进程B的起点同步:
SYNCHRONOUS |--------A--------| |--------B--------|
另一方面,异步进程的起点和终点不同步:
ASYNCHRONOUS |--------A--------| |--------B--------|
在进程A与进程B重叠的地方,它们是并发或同步运行的(字典定义),因此造成了混淆。
更新:Charles Bretana改进了他的答案,所以这个答案现在只是一个简单的(可能过于简化了)助记符。
当您同步执行某项任务时,您需要等待该任务完成后才能继续执行另一项任务。当您异步执行某个任务时,您可以在它完成之前转移到另一个任务。
在操作系统上下文中,这对应于在“线程”上执行进程或任务。线程是作为工作单元存在的一系列命令(代码块)。操作系统在处理器核心上运行给定的线程。然而,处理器内核一次只能执行一个线程。它没有同时运行多个线程的概念。操作系统可以通过运行每个线程一小段时间(比如1ms),并在线程之间不断切换,来提供同时运行多个线程的假象。
现在,如果您在混合中引入多个处理器核心,那么线程可以同时执行。操作系统可以将时间分配给第一个处理器核心上的一个线程,然后将相同的时间块分配给不同处理器核心上的另一个线程。所有这些都是关于允许操作系统管理任务的完成,而您可以继续在代码中执行其他事情。
异步编程是一个复杂的主题,因为当您可以同时进行这些事情时,它们是如何结合在一起的语义。关于这个主题的文章和书籍数不胜数;看看吧!
同步执行意味着在单个系列中执行。A - C > B - > - > D。如果您正在调用这些例程,则A将运行,然后结束,然后B将开始,然后结束,然后C将开始,等等。
使用异步执行,你开始一个例程,并让它在后台运行,同时你开始下一个例程,然后在某个时候,说“等待这个完成”。更像是:
开始A->B->C->D->等待A完成
这样做的好处是,当A仍在运行时(在后台,在一个单独的线程上),您可以执行B、C和或D,因此您可以更好地利用资源,减少“挂起”或“等待”。
是的,同步的意思是同时,从字面上看,它的意思是一起做功。世界上的多个人/物体可以同时做多件事,但如果我们看看计算机,它说同步意味着进程一起工作,意味着进程依赖于另一个的返回,这就是为什么它们以适当的顺序一个接一个地执行。异步意味着进程不能一起工作,它们可以同时工作(如果在多线程上),但是独立工作。
同步与异步
同步和异步操作是关于下一个任务相对于当前任务的执行顺序。
让我们看一个例子,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并行]