零、前言

  这里整理摘录了我了解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. htm,css,javascript及其他的注释方式

    转自:http://www.cnblogs.com/dapeng111/archive/2012/12/23/2829774.html 一.HTML的注释方法<!-- html注释:START ...

  2. numpy和matploptlib

    numpy Numpy介绍 编辑 一个用python实现的科学计算,包括:1.一个强大的N维数组对象Array:2.比较成熟的(广播)函数库:3.用于整合C/C++和Fortran代码的工具包:4.实 ...

  3. 自学大数据(hadoop)第一天

    熟悉linux系统 1.安装linux系统-ubuntu 官网链接:https://www.ubuntu.com/download 下载ubuntu desktop 即可,拖拽到VMvare里即可安装 ...

  4. 团队第四次 # scrum meeting

    github 本此会议项目由PM召开,召开时间为4-8日晚上10点 召开时长15分钟 任务表格 袁勤 负责编写登陆逻辑 https://github.com/buaa-2016/phyweb/issu ...

  5. JAVA WEB项目中开启流量控制Filter

    Flow Control:控流的概念 主要是用来限定server所能承载的最大(高并发)流量峰值,以免在峰值是Server过载而宕机,对于WEB系统而言 通常是分布式部署,如果请求并发量很大,会导致整 ...

  6. express+websocket+exec+spawn=webshell

    var child_process = require('child_process'); var ws = require("nodejs-websocket"); consol ...

  7. openssl error while loading serial number

    unable to load number from D:/Program Files/OpenSSL-Win64/bin/demoCA/serialerror while loading seria ...

  8. iOS如何转换十三位的时间戳

    //将十三位的时间戳转换为日期 - (NSString *)getDate:(NSString *)jsonDate { //jsonDate类似这种/Date(1447659630000)/ NSA ...

  9. java8-函数编程

    在Function里面看到一个很奇怪的代码 static <T> Function<T, T> identity() { return t -> t; } 手动写了几个代 ...

  10. 深度原理与框架-图像超分辨重构-tensorlayer

    图像超分辨重构的原理,输入一张像素点少,像素较低的图像, 输出一张像素点多,像素较高的图像 而在作者的文章中,作者使用downsample_up, 使用imresize(img, []) 将图像的像素 ...