反应式编程与基于线程的编程

Reactive Programming vs Thread Based Programming

我是这个概念的新手,想对这个话题有一个很好的理解。 为了说明我的观点,我想打个比方。

让我们以Node JS为例,它是单线程的,使用事件循环提供快速IO操作。现在这是有道理的,因为它是单线程的,并且不会被任何任务阻塞。

在 Java 中使用 reactor 研究反应式编程。我遇到了这样一种情况,当一个对象订阅并且发生了一些延迟事件时,主线程被阻塞。 然后我开始了解 subscribeOn.boundedElastic 的概念以及更多类似的管道。

我知道他们正试图通过将这些订阅者移动到其他线程来使其异步。

但是如果是这样的话那为什么是异步的。不是基于线程的编程吗? 如果我们试图实现 Node JS 的异步行为,那么根据我的观点,它应该在单线程中。

我的问题总结是:

所以我不明白使用或调用反应式编程作为异步或函数式编程的事实有两个原因

  1. 主线程被阻塞
  2. 我们可以管理线程并且可以 运行 它在另一个池中。 Runnable service/callable 我们也可以定义。

首先你不能比较asynchronousfunctional programming。这就像将岩石与香蕉进行比较。它是两个独立的东西。

Functional programming 与其他类型的编程相比,如 object oriented programmingprocedural programming

Reactor 是一个 java 库,java 是一种具有函数式特征的面向对象编程语言。

Asynchronous我会用维基百科的内容来解释

Asynchrony, in computer programming, refers to the occurrence of events independent of the main program flow and ways to deal with such events.

所以基本上如何处理应用程序“周围”的东西,这不是程序主要流程的一部分。

Blocking 相比,维基百科再次:

A process that is blocked is one that is waiting for some event, such as a resource becoming available or the completion of an I/O operation.

传统的 servlet 应用程序通过为每个请求分配一个线程来工作。

所以每次有请求进来时,都会产生一个线程,这个线程跟随请求直到请求 returns。如果在此请求期间有某些阻塞,例如从操作系统读取文件,或向其他服务发出请求。分配的线程会阻塞等待,直到文件读取完成,或者请求返回等

Reactive 与 subscribersproducers 一起工作,并大量使用 observer pattern。这意味着一旦某些东西阻塞,反应器就可以使用该线程并将其用于其他事情。然后解除阻塞,任何线程都可以从它停止的地方继续。这可确保每个线程始终处于使用状态,并且使用率为 100%。

reactor 中处理的所有事情都由 event loop 完成,事件循环是一个单线程循环,它只是尽可能快地处理事件。 Schedulers 在事件循环中安排要处理的事情,处理完后,调度程序会获取结果并继续。

如果你只是 运行 反应堆,你会得到一个默认的调度程序,它将完全自动地为你安排事情。

但是假设您遇到了阻碍。那么你将停止事件循环。一切都需要等待那件事完成。

当您 运行 一个完全反应式的应用程序时,您通常会在启动期间为每个核心获得一个事件循环。这意味着假设你有 4 个核心,你有 4 个事件循环,你阻塞了一个,然后在阻塞期间你的应用程序 运行s 慢了 25%。

慢 25% 很多!

好吧,有时您会遇到无法避免的阻碍。例如,没有非阻塞驱动程序的旧数据库。或者您需要在阻塞庄园中从操作系统中读取文件。那你好吗?

反应堆团队构建了一个回退,因此如果您将 onSubscribe 与它自己的弹性线程池结合使用,那么您将为该单个订阅者恢复旧的 servlet 行为以达到特定的 say端点等

这确保您可以 运行 完全反应性的东西与旧的遗留阻塞物并排。所以也许一些请求使用旧的 servlet 行为,而其他请求是完全非阻塞的。

你的问题不是很清楚所以我给你一个很不明确的答案。我建议您阅读 reactor 文档并尝试所有示例,因为大部分信息都来自那里。