java NIO知多少

背景

Linux系统中的IO操作内部相当复杂,下面是一张带图片的LinuxIO相关层级关系:

下面是一个简化版本Linux内部IO层级图:

对此我的理解,java程序员版本的IO理解:

java中的IO

从最早bio的只支持阻塞的bio(同步阻塞)

到默认阻塞支持非阻塞nio(同步非阻塞+同步阻塞)

再到aio(异步非阻塞)

NIO

  • FileChannel:从文件读取数据的
  • DatagramChannel:读写UDP网络协议数据
  • SocketChannel:读写TCP网络协议数据
  • ServerSocketChannel:可以监听TCP连接

示例代码: socket https://github.com/victorsheng/verification-everything/tree/master/io/src/main/java/socket/nio file https://github.com/victorsheng/verification-everything/tree/master/io/src/main/java/file/nio

AIO

示例代码: socket https://github.com/victorsheng/verification-everything/tree/master/io/src/main/java/socket/aio file https://github.com/victorsheng/verification-everything/tree/master/io/src/main/java/file/aio

NIO的应用

作为jdk的基础类库,被很多应用使用了,此处列举了几个常见的

NIO的应用例子1:tomcat

http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Connector_Comparison

NIO的应用例子2:jetty

Prior to Jetty 9, the type of the connector reflected both the protocol supported (HTTP, HTTPS, AJP, SPDY), and the nature of the implementation (NIO or BIO). From Jetty 9 onwards there is only one prime Connector type (ServerConnector), which is NIO based and uses Connection Factories to handle one or more protocols.

https://www.eclipse.org/jetty/documentation/9.4.x/quickstart-config-what.html#intro-jetty-configuration-connectors

NIO的应用例子3:netty

 作为nio最常用的封装类库

总结

nio更多解决的是线程资源的浪费,而非单个操作响应时间的提升

使用NIO != 高性能,当连接数<1000,并发程度不高或者局域网环境下NIO并没有显著的性能优势。

NIO并没有完全屏蔽平台差异,它仍然是基于各个操作系统的I/O系统实现的,差异仍然存在。使用NIO做网络编程构建事件驱动模型并不容易,陷阱重重。
推荐大家使用成熟的NIO框架,如Netty,MINA等。解决了很多NIO的陷阱,并屏蔽了操作系统的差异,有较好的性能和编程模型。

参考文章

https://lrita.github.io/2019/03/13/the-internal-of-file-syscall/
https://tech.meituan.com/2016/11/04/nio.html

posted @ 2019-08-16 09:02 聚变归来 阅读(...) 评论(...) 编辑 收藏