java - 为什么 Java NIO 可以优于标准的 Java 套接字?

标签 java sockets nio

最近我在玩 Java 套接字和 NIO 来编写服务器。尽管我仍然不太清楚为什么 Java NIO 可以优于标准套接字。在使用这两种技术中的任何一种编写服务器时,在大多数情况下,它归结为具有接受连接并将它们进一步传递给工作线程的调度程序线程。

我读到在线程模型中每个连接需要一个专用线程,但我们仍然可以创建一个固定大小的线程池并重用它们来处理不同的连接(这样创建和拆除线程的成本减少了)。

但是对于 Java NIO,它看起来很相似。我们有一个线程接受请求,一些工作线程在接收到数据时处理数据。

我发现 Java NIO 更好的一个例子是维护许多非繁忙连接的服务器,如聊天客户端或 http 服务器。但不能真正理解为什么。

最佳答案

有几个不同的原因。

  1. 通过Selector 使用多路复用 I/O 可以节省大量线程,从而节省大量线程堆栈,从而节省大量内存。另一方面,它将调度从操作系统转移到您的程序中,因此它可能会占用您一些 CPU,还会使您很多编程复杂化。考虑到 select() 是在备选方案是更多进程而不是更多线程时设计的,与使用线程和将节省的编程资金花在更多内存上相比,额外的复杂性是否真的值得,实际上值得商榷。

  2. MappedByteBuffers 是一种比 java.io 或使用 java.nio.channelsByteBuffers 更快的文件读取方式.

  3. 如果您只是从一个 channel 复制到另一个 channel ,使用“直接”缓冲区可以使您不必将数据从 native JNI 空间复制到 JVM 空间,然后再复制回来;或者使用 FileChannel.transferTo() 方法可以避免将数据从内核空间复制到用户空间。

关于java - 为什么 Java NIO 可以优于标准的 Java 套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17126998/

相关文章:

java - 如何使用 hibernate 逆向工程工具生成带有 ejb3 注释的 pojo?

java - do-while 循环什么时候比 while 循环更好?

java - 禁用的 Jbutton Swing 无法正常工作

Qt/C++ : How to get remote PC (communication peer) MAC address?

java - 如何检查 WatchService 跟踪的文件夹?

java - 如何设置 Jenkins 从应用程序内具有依赖关系的其他 Maven 项目构建 Maven 项目

node.js - 一次与两个用户随机聊天(Socket.io)

C++套接字设计

java-nio : send from different thread than selecting

java - 使用 Java 在 Zip 文件中重新创建文件夹结构 - 空文件夹