非阻塞样式的好处是什么?

Вад*_*нюк 2 java multithreading asynchronous nonblocking project-reactor

我正在尝试了解非阻塞编程的核心原理(以及项目反应堆之类的框架)。主要思想是使“线程池”具有确定数量的线程(执行程序)和在此执行的任务。我们不应有任何阻塞的线程。在“用户代码”中,我们只运行一些要执行的内容并留下回调(与结果有关)。出“用户”线程未被阻止,对。但是,如果我的任务取决于某些jdbc查询,该怎么办?我的任务将请求此查询,然后将被阻止等待结果,对吗?因此,该线程被阻止。

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

如果我的线程池由2个执行程序组成,并且两个执行程序都被阻止等待,则其他任务将不会执行,对吗?如何避免呢?创建两个以上的线程?

Jes*_*per 7

线程是相对昂贵的系统资源。例如,每个线程都需要用于调用堆栈的内存。多少取决于操作系统,但是通常大约为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,但尚未准备好。