java - 非阻塞风格有什么好处?

标签 java multithreading asynchronous nonblocking project-reactor

我试图理解非阻塞编程(以及像项目 react 器这样的框架)的核心原理。主要思想是拥有具有确定数量的线程(执行器)和在那里执行的任务的“线程池”。我们不应该有任何阻塞的线程。在“用户代码”中,我们只是运行一些东西来执行并留下回调(如何处理结果)。 “用户”线程没有被阻塞,对吧。但是如果我的任务依赖于某些 jdbc 查询怎么办?我的任务会请求这个查询,然后会被阻塞等待结果,对吗?因此,该线程被阻塞。

但是我们避免创建线程(这很昂贵)。这是这种风格的核心优势吗?

如果我的线程池由 2 个执行器组成,并且两个执行器都被阻塞等待某件事,那么其他任务将不会被执行,对吗?如何避免呢?创建超过 2 个线程?

最佳答案

线程是相对昂贵的系统资源。例如,每个线程都需要内存用于调用堆栈。该大小取决于操作系统,但通常约为 1 或 2 MB。这意味着启动数千个线程并不是一个好主意 - 仅仅在 1000 个线程的调用堆栈上就会浪费 1 或 2 GB 内存。

因此,为了更有效地完成工作,您需要限制线程数量,例如使用线程池来处理工作。线程池可以管理正在使用的线程数量。

但是,假设您有一个包含 10 个线程的线程池,然后有 10 个请求进来。每个线程都将被保留来处理一个请求。当它们很忙时,您无法处理请求#11,因为没有空闲线程。当您使用阻塞 I/O 时,即使所有 10 个线程都没有执行任何操作(等待 I/O 完成),也无法处理请求 #11...

当您使用非阻塞 I/O 时,线程永远不需要等待 I/O - 因此,当处理请求#3 因为需要 I/O 操作的结果而被挂起时,正在处理的线程它可以暂时切换到处理其他请求。

因此,通过非阻塞 I/O,您永远不会有等待线程,并且可以更有效地使用系统资源。

只有当您从系统的前端到后端使用非阻塞 I/O 时,这才有效。如果在后端您使用 JDBC(这是一种阻塞 API),那么您将失去非阻塞 I/O 的全部优势。

因此,如果您的后端有一个数据库,那么如果您有一个支持非阻塞 I/O 的数据库,这种方法效果最好。一些 NoSQL 数据库(例如 MongoDB)支持此功能,而对于某些关系数据库,有特殊的驱动程序/API 可以支持此功能。在这种情况下,您不会使用 JDBC,因为 JDBC 本质上是一种阻塞 API。

Oracle 正在为关系数据库开发一个新的 API,暂定名为 ADBA这将允许您对关系数据库进行非阻塞/异步 I/O,但它还没有准备好。

关于java - 非阻塞风格有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53430186/

相关文章:

Java Arrays.sort(test) 对两个数组进行排序

java - 单击 JFrame 中的“搜索”按钮应打开一个搜索栏

java - 删除数组中的重复项,末尾补零

java - 为什么 Gson 将 Integer 解析为 Double?

c# - 如何异步更新 winform?

java - 生产者-消费者场景。我有一个生产者和多个消费者

c# - 我如何测试 FileSystemWatcher 引发正确的事件?

c# - 从多个线程渲染到单个 Bitmap 对象

wpf - 如何在后台线程上执行 WPF 筛选器?

java - asyncTask 中的 findViewById()