【问题标题】:Non-blocking Async IO in JavaJava中的非阻塞异步IO
【发布时间】:2020-04-26 15:55:02
【问题描述】:

有没有什么方法可以在不阻塞任何线程(包括后台线程)的情况下在 Java 中进行异步 IO?来自C#,我对async IO的理解是调用的时候就可以了

await ReadAsync()

调用线程(线程池的一部分)进入ReadAsync 函数,在某些时候从操作系统内核调用异步读取函数,然后将自身添加回线程池以获取其他Tasks。读取完成后,线程池会收到通知,另一个线程会获取 Task 的其余部分。

另一方面,在 Java 中,documentationthis 的答案似乎表明异步 IO 函数只是由后台线程调用然后阻塞。这似乎性能较差。有什么方法可以在 Java 中实现真正的非阻塞 IO?

【问题讨论】:

标签: java asynchronous io


【解决方案1】:

AsynchronousFileChannel.open()根据运行环境返回不同实现的实例。在 Windows 上,它应该返回一个 WindowsAsynchronousFileChannelImpl 的实例,它使用 I/O 完成端口并避免阻塞 IO 操作上的线程。线程池中的线程仅用于分发结果,不会阻塞,除非最终用户程序员阻塞了该线程。

RxIo 构建在 AFC 之上,提供与同步 Files 类等效的 AsyncFiles,但具有异步 API。利用CompletableFuture(相当于.net Task)的延续传递风格,您可以在不阻塞的情况下读取文件内容:

AsyncFiles
  .readAll(path)
  .thenAccept(body ->     /* invoked on completion */)
  .exceptionally(excep -> /* invoked on error*/

您可以运行RxIo 的单元测试并在open() 处放置一个断点并检查WindowsAsynchronousFileChannelImpl 的实现。

【讨论】:

  • 知道了。它是如何在 Linux 上实现的?那里也没有阻塞吗?
  • 我认为不是。从对这个答案stackoverflow.com/questions/39501924/… 的观察来看,似乎在 Linux 上,每个 IO 操作都会阻塞一个线程。
猜你喜欢
  • 2014-09-25
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-28
  • 1970-01-01
相关资源
最近更新 更多