阻塞代码比非阻塞代码有什么优势?

What are the advantages to blocking code over non-blocking code?

我正在学习 JavaScript 和 Node.我了解异步的工作原理。我明白为什么它可以显着加快速度。

我看到其他语言(如 Ruby 和 Java?)被设计为阻塞。为什么?

我有一个模糊的想法,您可以使用线程来处理需要很长时间的情况。与异步处理相比,这样做的优点和缺点是什么?

首先值得注意的是 javascript 几乎永远不会允许您访问多个内核。因此,您(通常)不会看到非阻塞代码带来的速度提升。这是其他语言的非阻塞代码的主要好处之一。在 javascript 中,异步代码通常用于处理您不想停止一切并等待事件的事件(例如用户输入或文件下载),因为它可能需要一段时间(或永远不会发生) .异步代码的主要缺点是代码复杂。每当您编写异步代码时,您都需要注意两个线程同时处理一个对象等等。

阻塞或者同步代码容易写,默认单线程行为。当每个任务都依赖于下一个任务时,阻塞代码就有意义了。在多处理器和多线程之前,这是历史上唯一可用的选择。

创建非阻塞、异步、多线程编程是为了在可以并行执行多个任务的情况下提高性能。这提高了性能,但以增加复杂性为代价,使代码维护更加困难。

还有阻塞的 JavaScript 运行时环境,例如 RingoJS 或早期的 Node 竞争对手。如果阻塞代码很长 运行 并且不能拆分成不同的部分,则它具有优势。如果您不能依赖非阻塞 IO 作为您的基本调度间隔,阻塞可能是更好的解决方案。

请考虑以下场景:您的传入请求不是几 KB 的内容,而是数百兆字节。您的代码会一次性读取所有传入的字节。如果您在事件循环中解析此类请求,它将阻塞队列中的所有其他请求,这些请求必须等待处理。阻塞运行时使这更容易,因为一个线程可能从 CPU 中拉出,另一个线程继续处理他的大输入,但两者都是并行活动的。

阻塞环境中的真正问题是共享状态。如果很多线程访问同一个变量,就需要同步,这会导致大量资源浪费。这就像在非阻塞环境中阻塞事件循环:只是不要这样做。

我个人觉得阻塞代码更容易阅读和理解,因为它遵循一行执行并且没有回调或期货。但这取决于您要解决的问题。双方在各种场景下各有利弊。