我已经看到了许多主题,它们将较旧的Java io模型与较新的Java nio模型进行了比较,前者是同步/阻塞,而后者是异步/非阻塞。因为nio是非阻塞的,所以在需要并发处理大量并发连接而不分配大量线程(由于上下文切换/内存使用而无法很好地扩展)的情况下,它比java io更适合。

我在使用此参数时遇到的问题是,IO与NIO的比较总是给出每个连接使用线程的IO示例。使用Java IO的开发人员可以简单地分配有限数量的线程(线程池)来阻止IO操作(即文件读取或数据库查询)并将它们排队吗?假设我正在使用Java的ServerSocket类从头开始构建http服务器。假设我从客户端收到一个请求,该请求要求我进行数据库查询,这是由于JDBC规范而导致的阻塞操作。我是否可以简单地将数据库查询排队到ThreadPool并在池完成处理后将作业递给要运行的回调?当然,我正在分配线程来处理io-bounds请求,但是线程数是有限的。由于IO操作通常(在一定程度上)是同步的,因此尝试为每个db查询分配一个线程或为每个文件读/写分配线程是毫无意义的。

这样,您可以获得线程和异步编程的好处,而不必分配过多的线程。

我在此模型中看到的唯一弱点是,如果所有io绑定(bind)操作都被阻塞(可能是由于编程错误),则将来的排队请求将被搁置,直到它们被取消阻塞或超时。主要逻辑仍然是并发的,但IO则不是。

因此,问题是:NIO是否解决了上面描述的模型无法解决的任何问题(排除了我刚刚提到的潜在弱点)?

最佳答案

当然,您可以使用一个池和有限数量的线程来执行此操作,并处理您自己的I/O,但是您基本上将复制NIO为您提供的功能,但又无法利用 native API的优势。

您的系统无法很好处理的问题之一是成千上万个套接字执行缓慢的I/O,这可能是处理服务器推送,BitTorrent客户端或非常繁忙的内容服务器所需的。

较传统的请求/响应系统可以在您的解决方案中正常工作,但是,同样,它们也可以在每个请求的线程中正常工作,因为通常遇到的第一个瓶颈将是CPU或内存消耗。

10-04 15:01
查看更多