关于NIO的学习理解

以下仅仅介绍各个组件的用途与为什么会出现这些组件,不提供API的详解

NIO是什么?

全称new input output。针对于文件系统的IO,提供内存映射以提高IO效率;对于网络IO,提供一个线程可以管理多个连接的能力。

为什么能提高IO效率?

本地文件系统

针对于本地文件系统,不支持选择通道+IO多路复用。文件要被应用所访问到,路径为  磁盘-->>>内核空间-->>>用户空间,磁盘到内核空间有一个DMA控制器,DMA控制器从磁盘加载数据是不需要消耗CPU的,但内核空间到用户空间需要消耗CPU,NIO中的buffer组件能提供内存映射,避免了内核空间把文件内容进行中转的CPU消耗,如下图,图1为没用内存映射,图2用了内存映射

关于NIO的学习理解

网络IO

针对于网络IO,支持可选择通道+多路复用,提供了以下模型,选择器可以选择就绪的通道进行操作,如下图:

关于NIO的学习理解

socket+nio与传统socket+bio优势

一个选择器可以管理多个客户端通道;如果是传统的方式,由于socket是阻塞的,所以为了解决多个客户端连接的问题,需要开多个线程,一个线程处理一个客户端,由于线程资源宝贵且数量有上限,无法处理并发高的情况。

组件

Buffer缓冲区

buffer是用于承载于通道两端实体数据的容器,类图如下:

关于NIO的学习理解

只有ByteBuffer才能被管道所使用,因为操作系统的数据存储都是基于字节的。字节缓冲区又分为直接缓冲区与非直接缓冲区,直接缓冲区就是用了内存映射。

直接缓冲区的好处:

1. 基于内存映射,IO效率高

2. 由操作系统分配内存,所以不占用JVM的内存

直接缓冲区的坏处:

1. 需要操作系统来分配调度,所以代价昂贵

视图缓冲区与字节缓冲区

视图缓冲区只能由字节缓冲区生成,视图缓冲区是原始类型的缓冲区,与原缓冲区数据共享,但是单独维护了limit,position等重要属性。

通道Channel

通道是连接于两端实体的管道,两端数据的传递把数据放入buffer,然后经过管道传输。

注意: 只有继承了SelectableChannel的之类才能配合选择器使用

通道类图如下:

关于NIO的学习理解

FileChannel不支持选择通道+多路复用,因为没有继承SelectableChannel

SelectionKey

由通道注册到选择器后返回的对象,封装了 选择器与通道的关系和通道的就绪状态和感兴趣的操作。

Selector选择器

用于选择出已经准备就绪的通道。

关于针对于网络IO各个组件的关系图如下:

关于NIO的学习理解