阻塞与同步、非阻塞和异步有啥区别? [复制]

Posted

技术标签:

【中文标题】阻塞与同步、非阻塞和异步有啥区别? [复制]【英文标题】:What's the differences between blocking with synchronous, nonblocking and asynchronous? [duplicate]阻塞与同步、非阻塞和异步有什么区别? [复制] 【发布时间】:2012-01-15 01:21:05 【问题描述】:

我正在阅读“Java 操作系统概念”。我对这个概念感到很困惑 阻塞和同步,它们有什么区别?

【问题讨论】:

请参考本博客voinici.ceata.org/~sana/blog/?p=248和***.com/questions/2625493/… 【参考方案1】:

同步意味着工作在调用函数的线程中完成,并且方法在完成之前不会返回。

异步方法立即返回,因为另一个线程完成工作并在工作完成时引发标志或触发事件。

阻塞意味​​着执行阻塞事件的线程将等待直到事件发生。例如,您尝试从套接字读取,但没有人向您发送消息。在消息从套接字中恢复之前,阻塞调用不会返回。

好吧,非阻塞意味着与阻塞相反,意味着非阻塞调用是异步的。

【讨论】:

谢谢克罗诺斯。似乎同步和阻塞没有区别,他们都需要等待一个工作或事件完成,然后他们才能继续做下一个工作或事件。对吗?【参考方案2】:

阻塞可能与同步相同,也可能不同,具体取决于上下文。当我们谈论方法调用时,同步调用也可以说是阻塞的(我稍后会回到这个),因为调用方法的线程在方法返回之前无法继续前进。这种情况下的反义词是异步的。

在锁术语中,如果等待获取锁的线程处于挂起模式直到锁可用(或直到超时),则称锁处于阻塞状态。在这种情况下的反义词是非阻塞锁,这意味着即使无法获取锁,线程也会立即返回。这可以用来实现所谓的自旋锁,即在保持线程活跃的同时不断轮询锁的状态。

话虽如此,您可以推断概念之间的区别:同步通常意味着必须等待回复才能线程向前移动的活动。阻塞是指线程处于等待状态(通常意味着它不会被调度执行,直到某些事件发生)。从这里您可以得出结论,同步调用可能涉及阻塞行为,也可能不涉及,具体取决于底层实现(即它也可能在旋转,这意味着您正在使用异步调用模拟同步行为)。

【讨论】:

嗨,你能举一个阻塞调用不同步的例子吗?谢谢 @Always_Beginner:根据定义,阻塞调用将始终是同步的,因为这意味着控制流在等待某事完成时会阻塞。然而,同步调用可能不会阻塞。【参考方案3】:

我将它们分类如下:

阻塞 - 线程将等待操作直到成功或失败(突出显示“将等待”,失败通常是超时)

同步 - 线程将在到达其后的任何行之前通过成功或失败完成操作(突出显示操作完成)

非阻塞 - 线程不会等待动作完成,立即执行动作

异步 ​​- 另一个线程(逻辑或物理)将完成操作或使用回调通知它已准备好,在执行以下命令之前不会等待。 注意:从这里开始异步的名称,因为你不能确定命令将按什么顺序执行

【讨论】:

【参考方案4】:

阻塞 - 如果操作等待某个事件完成,则称该操作具有阻塞行为。例如:如果锁不可用,则线程可能会在事件发生时进入等待状态,直到锁可用。这样的操作被称为阻塞。

同步 - 同步调用可以通过 http 协议的示例轻松理解,其中客户端等待来自服务器的回复然后继续。同步调用可以是阻塞的也可以是非阻塞的。

异步 ​​- 一个方法可以异步调用其他方法。调用后它可以继续执行下一条指令。当被调用的方法完成它的执行时,它会向调用者方法发送成功或失败的回复/回调。

非阻塞 - 非阻塞行为就像检查该实例的条件。例如,如果锁不可用,它不会像阻塞操作一样等到它可用。此外,我们需要反复检查锁的可用性,因为不会像异步调用那样回调。

总结: 阻塞总是同步的。

同步调用有阻塞操作,如果它等待某个事件完成,调用者方法可能会进入等待状态。

同步调用是非阻塞的,如果它在执行下一条指令之前反复检查某个事件是否发生。调用方方法不会在某些事件完成时进入等待状态。

异步调用不能阻塞,它涉及到需要处理的被调用方法的回调。

【讨论】:

如果我将 await 放在异步调用上会不会使它阻塞? 这个blog post(尽管示例是在 Python 中)与您关于异步不能阻塞并且同步总是阻塞的陈述相矛盾。

以上是关于阻塞与同步、非阻塞和异步有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

正确理解同步/异步和阻塞/非阻塞的区别:

同步/异步和阻塞/非阻塞

怎样理解阻塞非阻塞与同步异步的区别?

阻塞非阻塞与同步异步的区别

怎样理解阻塞非阻塞与同步异步的区别?

同步异步与阻塞非阻塞的区别