零、前言

  这里整理摘录了我了解NIO的一些笔记。
  参考资料:
  3、Java NIO vs. IO

一、NIO与BIO的简单对比

  Java中,传统的IO,又称BIO(Blocking IO,阻塞式IO)。BIO是面向流(stream)的,阻塞的。
  NIO(Non-Blocking IO,非阻塞式IO)。NIO是面向缓存(buffer)的,非阻塞的。
  1、面向流与面向缓存
BIO是面向流模式,意味着数据只能读取一次,没有缓存,不能在数据中向前向后移动;
NIO是面向缓存模式,指数据被缓存到一个数据块中,数据可以重复读写,可以在数据中向前向后移动;
  2、阻塞与非阻塞
  BIO是阻塞式的,这意味者当一个线程调用读/写方法的时候,这个线程会被阻塞,直到读/写操作完成,这个时间线程不能再干其它事情。
  NIO是非阻塞式的,一个线程请求读/写数据到一个通道上时,不需要等待读/写完成,该线程可以干其它事情。

二、NIO的几个核心部分

  NIO组件图如下:
(图1、NIO组件图)

  Buffer:

  1、一块缓存区,内部使用字节数组存储数据,并维护几个特殊变量,实现数据的反复利用。
  2、几个特殊变量:
  – position – 初始值为0,用于表示当前可以读/写数据的位置,当读/写一个数据后,position向前移动到下一个位置;
  – mark – 初始值为-1,用于备份当前position;
  – limit – 写模式:表示Buffer最多能写多少数据、读模式:表示最多读取多少数据;
  – capacity – 缓存数据的大小
(图2、Buffer内部结构示意图)
  3、Buffer的几个方法:
  mark() – 把position值赋给mark
  reset() – 把mark值还原给position
  clear() – 重置几个变量,恢复状态,数据不会被删除
  flip() – 从写模式变成读模式(怎么变?不是很懂)
  rewind() – 重置position为0,mark为-1
  目前Buffer的实现类(按类型,省略Buffer后缀)有:
  Byte、Char、Double、Float、Int、Long、Short、MappedByte
(图3、Buffer类继承图)
  注:Buffer内存空间的申请可以从JVM堆内存中申请或者直接物理内存中申请,如HeapByteBuffer和DirectByteBuffer

  Channel:

  1、NIO把它支持的I/O对象抽象为Channel,Channel又称“通道”,类似于原来I/O中的流(Stream),Channel与Buffer相连。
  2、通道与流的对比:
对比项
通道
方向
单向
双向,可写可读
是否阻塞
读写阻塞
读写异步
缓存
可以选择性读入缓存
必须先读/写到缓存
  3、关于Channel先读/写到缓存的问题:
  Channel的读/写到缓存的策略导致了Channel的read/write方法把数据复制了两次(为什么要这样?):
  read方法 – 申请一块缓存,先读取数据到缓存(由native方法实现),再把数据从缓存读取到用户自定义的缓存;
  write方法 – 申请一块缓存,先从用户自定义的缓存中数据写到缓存中,再把数据从缓存中写入其它地方,如文件(由native方法实现)

  Selector:

  1、Selecttor相当于一个监听器,不断地去轮询Channel,示意图如下:
(图4、Selector示意图)
  2、Channel需要在Selector上注册事件。
  比如:SocketChannel有如下事件:connect(客户端连服务端事件)、accept(服务端接收连接事件)、read(读事件)、write(写事件)
  3、Selector如何同时管理多个socket?
  3.1、Selector的实例化由SelectorProvider类实现。
  3.2、Selector初始化时会实例化PollWrapper、SelectionKeyImpl数组和Pipe。
  – PollWrapper
  作用:对pollfd(一个8位结构体,前4位保存socket句柄,后4位保存事件)进行管理。
  操作:提供对pollfd句柄插入和事件插入的操作。
  – SelectionKeyImpl
  作用:表示SelectableChannel在Selector中注册的标记/句柄,一个SelectionKeyImpl代表和一个Channel和一个事件的关联关系。
  操作:提供插入事件的操作,最终会插入到pollfd结构体里面。
  – Pipe
  作用:表示两个线程之间的单向数据连接,数据会从sink通道写入,从source通道读取。
  Selector的注册过程,实际上是把通道和事件的信息维护起来;
  注:我对这块的理解是最终Channel、Event的信息会落地到pollfd数组里,也就是说Channel的注册、SelectionKey和该数组密切相关。
  4、这里Selector已经维护通道和事件的信息,调用select方法,然后遍历SelectionKeyImpl找到对应的SelectionKeyImpl,获取Channel,最后读取消息。
    – select方法的核心是poll方法,该方法由native函数poll0实现对socket句柄(Fds)数组的操作。如果没有事件发生,则会阻塞,直到超时;

NIO学习笔记的更多相关文章

  1. Java NIO学习笔记

    Java NIO学习笔记 一 基本概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. 所有语言运行时系统提供执 ...

  2. 零拷贝详解 Java NIO学习笔记四(零拷贝详解)

    转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...

  3. Java NIO 学习笔记(七)----NIO/IO 的对比和总结

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  4. Java NIO 学习笔记(六)----异步文件通道 AsynchronousFileChannel

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  5. Java NIO 学习笔记(五)----路径、文件和管道 Path/Files/Pipe

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  6. Java NIO 学习笔记(四)----文件通道和网络通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  7. Java NIO 学习笔记(三)----Selector

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  8. Java NIO 学习笔记(二)----聚集和分散,通道到通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  9. Java NIO 学习笔记(一)----概述,Channel/Buffer

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  10. Java:NIO 学习笔记-3

    Java:NIO 学习笔记-3 根据 黑马程序员 的课程 JAVA通信架构I/O模式,做了相应的笔记 3. JAVA NIO 深入剖析 在讲解利用 NIO 实现通信架构之前,我们需要先来了解一下 NI ...

随机推荐

  1. vim YouCompleteMe 遇到的问题及解决

    问题1: 补充,升级gcc,g++ 到4.7以上的版本才能安装成功 github 官网 github https://github.com/Valloric/YouCompleteMe#ubuntu- ...

  2. [转][Oracle]清理归档日志

    来自:https://www.cnblogs.com/Roobbin/p/9617962.html 在Oracle 服务器,打开cmd命令行,执行以下命令: rman target / crossch ...

  3. note 6 函数

    函数 完成特定功能的一个语句组,这组语句可以作为一个单位使用,并且给它取一个名字 通过函数名执行 数学 function(x) = x^2 - 2x + 1 abs(x) #求x的绝对值 定义函数 定 ...

  4. localStorage溢出问题

    项目使用的store.js库 store.js库不能管理localStorage中的过期项到时清除,只能在再次调用get的时候才做处理,如果一直不调用get,过期了也还是占用着空间.溢出后,再储存项目 ...

  5. PROC IMPORT 选项

    GETNAMES=YES;导入源文件字段名作为SAS数据集的字段名MIXED=NO;若某一列中包含数值型和字符型变量,将数值型按照缺省值处理.若选的是YES则是将数值型转换成字符型存储,默认为NOSC ...

  6. 著名java博客

    http://blog.csdn.net/net19880504/article/details/20807403

  7. jmeter多sql查询

    背景:实现多条sql语句,取多个值的情况 步骤:1.JDBC Connection Configuration配置添加?allowMultiQueries=true 2.增加sql语句 ,查询或修改语 ...

  8. 《机器学习实战》之一:knn(python代码)

    数据 标称型和数值型 算法 归一化处理:防止数值较大的特征对距离产生较大影响 计算欧式距离:测试样本与训练集 排序:选取前k个距离,统计频数(出现次数)最多的类别 def classify0(inX, ...

  9. 73.纯 CSS 创作一只卡通狐狸

    原文地址:https://segmentfault.com/a/1190000015566332 学习效果地址:https://scrimba.com/c/cz6EzdSd 感想:过渡效果,圆角,定位 ...

  10. 解决Windows下mysql无法启动1067错误

    解决过程 查看服务发现mysql未启动   用cmd命令行启动提示启动失败 错误代码1067 打开时间查看器发现mysql错误记录信息为Fatal error: Can't open and lock ...