背景
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.
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