异步执行和同步执行之间的区别是什么?


当前回答

简单来说:

同步

你在排队买电影票。在你前面的每个人都买到之前,你不可能买到,在你后面排队的人也一样。

异步

你和很多人在一家餐馆里。你点餐。其他人也可以点他们的食物,他们不需要等你的食物煮好并端上来才可以点餐。 餐厅的工作人员在厨房里不停地做饭、上菜、接单。 人们的食物一做好就会端上来。

其他回答

当执行a>b>c>d>这样的序列时,如果我们在执行过程中遇到如下失败:

a
b
c
fail

然后我们从头开始:

a
b
c
d

这是同步的

然而,如果我们有相同的序列要执行:a>b>c>d>,我们在中间有一个失败:

a
b
c
fail

...但我们不是从头开始,而是从失败的地方重新开始:

c
d

...这就是所谓的异步。

我认为一个很好的方法是把它看作是一个经典的跑步接力赛

同步:流程就像同一个团队的成员一样,它们直到收到接力棒(前一个流程/运行者执行的结束)才会执行,但它们彼此都是同步的。

异步:在同一接力赛跑道上的不同团队的成员,他们将运行和停止,彼此异步,但在同一场比赛中(整体程序执行)。

这有意义吗?

关于同步执行的“同时”定义(有时会令人困惑),下面是一种理解它的好方法:

同步执行:一个代码块中的所有任务都在同一时间执行。

异步执行:一个代码块中的所有任务都不会同时执行。

我认为这是一个有点迂回的解释,但它仍然澄清了使用现实生活中的例子。

小例子:

让我们假设播放音频包含三个步骤:

从硬盘中获取压缩的歌曲 解压音频。 播放未压缩的音频。

如果你的音频播放器为每首歌依次执行步骤1、2、3,那么它就是同步的。你必须等待一段时间才能听到这首歌,直到这首歌真正被提取和解压。

如果你的音频播放器独立执行第1、2、3步,那么它就是异步的。ie。 当播放音频1(步骤3)时,如果它并行地从硬盘中获取音频3(步骤1),并且并行地解压音频2。(第二步) 你最终会听到这首歌,而不需要等待太多的取回和解压。

同步与异步

同步和异步操作是关于下一个任务相对于当前任务的执行顺序。

让我们看一个例子,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并行]