java - 非阻塞 API 是如何工作的?

标签 java multithreading asynchronous nonblocking

我一直在阅读Play Framework documentation并发现这句话令人困惑:

Note that you may be tempted to therefore wrap your blocking code in Futures. This does not make it non-blocking, it just means the blocking will happen in a different thread. You still need to make sure that the thread pool that you are using has enough threads to handle the blocking.

我的印象是所有这些非阻塞库都在自己的线程池中执行阻塞操作并返回 Future 对象,因此客户端代码不会阻塞。

但是这句话说它不会使其成为非阻塞。我错过了什么吗?是否有一些带有非阻塞库的高级魔法?

最佳答案

阻塞(如阻塞IO)在IO意义上意味着发起IO的线程进入 hibernate 状态,直到IO结果可用。

非阻塞 IO(或异步 IO)告诉相关驱动程序(内核、数据库驱动程序等)初始化 IO 操作,然后线程继续做其他事情。根据您使用的技术,您可以在回调(例如 Node.js)、 channel (Java)、 future (C++)、 promise (Node.js 的较新版本)中处理异步 IO 结果(甚至可能是异常),任务(.Net)、协程(C++17)等

异步IO不使用线程来使IO异步。这是这里的关键点。向线程池抛出阻塞 IO 操作不会使其异步,它只是阻塞在另一个线程上,并且非常不可扩展。它会使线程池中的线程被耗尽,因为随着越来越多的阻塞 IO 提交,它们只会阻塞。正如他们在文档中所写:

The most common place where a typical Play application will block is when it’s talking to a database. Unfortunately, none of the major databases provide asynchronous database drivers for the JVM

这意味着大多数数据库实现不为 Java 提供异步 IO - 向线程池抛出 SQL 查询将使线程池线程阻塞。这就是他们所说的意思:

Note that you may be tempted to therefore wrap your blocking code in Futures. This does not make it non-blocking, it just means the blocking will happen in a different thread.

正如我们之前所说,异步 IO 不会阻塞另一个线程上的 IO。

标准包java.nio提供了Java中真实异步IO的示例

关于java - 非阻塞 API 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41227272/

相关文章:

java - 如何使用不同的实现异步调用多个方法

c# - 使用 WebSocketClient ReceiveAsync 和缓冲区的正确方法是什么?

java - 当两个事务同时发生并相互影响时,根据另一个表的数据更新一行表的方法是什么

java - Java中如何终止这样的线程

linux - 在 Linux 上使用信号与 POSIX 线程

c++ - 等到事件发生

java - 在 .class 文件 Intellij 中设置断点

java - 运行java applet程序时出现问题

java - JAVA中从txt文件到二维双数组

c++ - 什么时候不应该使用[[carries_dependency]]?