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

提问

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

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

但是,与Java NIO相似.我们有一个线程可以接受请求,还有一些工作线程可以在接收到数据后对其进行处理.

我发现Java NIO更好的一个示例是维护许多不忙连接的服务器,例如聊天客户端或http服务器.但是真的不明白为什么.

最佳答案

有几个不同的原因.

>将多路I / O与选择器一起使用可以节省大量线程,从而节省大量线程堆栈,从而节省大量内存.另一方面,它将调度从操作系统转移到您的程序中,因此可能会花费您一些CPU,并且还会花费很多编程复杂性.考虑到select()是在替代方案有更多进程而不是更多线程的情况下设计的,因此与使用线程和节省更多内存所花的编程费用相比,是否值得额外的复杂化实际上值得商bat.
> MappedByteBuffers是一种比java.io或将java.nio.channels与ByteBuffers结合使用的读取文件的方式.
>如果您只是从一个通道复制到另一个通道,则使用“直接”缓冲区可以避免将数据从本机JNI空间复制到JVM空间并再次复制的麻烦.或使用FileChannel.transferTo()方法可以避免将数据从内核空间复制到用户空间.