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

2 java multithreading reactive-programming rx-java spring-webflux

我对这个概念很陌生,并且希望对这个主题有深入的了解。为了阐明我的观点,我想打个比方。

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

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

我了解到他们正在尝试通过将这些订阅者移动到其他线程来使其异步。

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

我的问题摘要是:

因此,由于两个原因,我不明白使用或调用反应式编程作为异步或函数式编程的事实

  1. 主线程被阻塞
  2. 我们可以管理线程并可以在另一个池中运行它。我们也可以定义可运行服务/可调用服务。

Tho*_*olf 6

首先你无法asynchronousfunctional programming. 这就像将一块岩石与一根香蕉进行比较。这是两个不同的事情。

Functional programming与其他类型的编程进行比较,例如object oriented programmingprocedural programming等等。

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

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

异步,在计算机编程中,是指独立于主程序流程的事件发生以及处理此类事件的方式。

因此,基本上如何处理应用程序“周围”的内容,这不是程序主流程的一部分。

Blocking再次与维基百科进行比较:

被阻塞的进程是正在等待某个事件的进程,例如资源变得可用或 I/O 操作完成。

传统 Servlet 应用程序的工作方式是为每个请求分配一个线程。

因此,每次收到请求时,都会生成一个线程,该线程会跟踪请求,直到请求返回。如果在此请求期间出现阻塞,例如从操作系统读取文件或向其他服务发出请求。分配的线程将阻塞并等待,直到文件读取完成,或者请求返回等。

subscribersReactive 与和 一起工作producers,并大量使用observer pattern. 这意味着一旦某些事情发生阻塞,reactor 就可以占用该线程并将其用于其他事情。然后它就被解除阻塞,任何线程都可以从它停止的地方继续。这可确保每个线程始终处于使用状态,并且利用率为 100%。

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

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

但假设你有什么东西阻塞了。那么你将停止事件循环。而一切都需要等待那件事完成。

当您运行完全响应式应用程序时,通常在启动期间每个核心都会获得一个事件循环。这意味着假设您有 4 个核心,您有 4 个事件循环,并且您阻塞了一个,那么在阻塞期间您的应用程序运行速度会慢 25%。

慢 25% 已经很多了!

好吧,有时你会遇到一些无法避免的阻碍。例如,没有非阻塞驱动程序的旧数据库。或者您需要以阻塞方式从操作系统读取文件。那你怎么办?

Reactor 团队构建了一个后备机制,因此,如果您onSubscribe与它自己的弹性线程池结合使用,那么您将为该单个订阅者恢复到特定端点等的旧 servlet 行为。

这确保您可以与旧的遗留阻塞事物并排运行完全反应性的事物。因此,也许某些请求使用旧的 servlet 行为,而其他请求则完全非阻塞。

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