关于NIO的学习理解
以下仅仅介绍各个组件的用途与为什么会出现这些组件,不提供API的详解
NIO是什么?
全称new input output。针对于文件系统的IO,提供内存映射以提高IO效率;对于网络IO,提供一个线程可以管理多个连接的能力。
为什么能提高IO效率?
本地文件系统
针对于本地文件系统,不支持选择通道+IO多路复用。文件要被应用所访问到,路径为 磁盘-->>>内核空间-->>>用户空间,磁盘到内核空间有一个DMA控制器,DMA控制器从磁盘加载数据是不需要消耗CPU的,但内核空间到用户空间需要消耗CPU,NIO中的buffer组件能提供内存映射,避免了内核空间把文件内容进行中转的CPU消耗,如下图,图1为没用内存映射,图2用了内存映射
网络IO
针对于网络IO,支持可选择通道+多路复用,提供了以下模型,选择器可以选择就绪的通道进行操作,如下图:
socket+nio与传统socket+bio优势
一个选择器可以管理多个客户端通道;如果是传统的方式,由于socket是阻塞的,所以为了解决多个客户端连接的问题,需要开多个线程,一个线程处理一个客户端,由于线程资源宝贵且数量有上限,无法处理并发高的情况。
组件
Buffer缓冲区
buffer是用于承载于通道两端实体数据的容器,类图如下:
只有ByteBuffer才能被管道所使用,因为操作系统的数据存储都是基于字节的。字节缓冲区又分为直接缓冲区与非直接缓冲区,直接缓冲区就是用了内存映射。
直接缓冲区的好处:
1. 基于内存映射,IO效率高
2. 由操作系统分配内存,所以不占用JVM的内存
直接缓冲区的坏处:
1. 需要操作系统来分配调度,所以代价昂贵
视图缓冲区与字节缓冲区
视图缓冲区只能由字节缓冲区生成,视图缓冲区是原始类型的缓冲区,与原缓冲区数据共享,但是单独维护了limit,position等重要属性。
通道Channel
通道是连接于两端实体的管道,两端数据的传递把数据放入buffer,然后经过管道传输。
注意: 只有继承了SelectableChannel的之类才能配合选择器使用
通道类图如下:
FileChannel不支持选择通道+多路复用,因为没有继承SelectableChannel
SelectionKey
由通道注册到选择器后返回的对象,封装了 选择器与通道的关系和通道的就绪状态和感兴趣的操作。
Selector选择器
用于选择出已经准备就绪的通道。
关于针对于网络IO各个组件的关系图如下: