零、前言

  这里整理摘录了我了解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. 基于fastadmin快速搭建后台管理

    FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架:开发文档 下面对环境搭建简要概述,希望后来者能少走弯路: 1. 百度搜索最新版wampserver, 安装并启动 ...

  2. C&C++类型定义typedef

    1.声明 1.1结构声明: struct { int n; double x,y; }; 1.2带结构标志的声明 struct point{ double x,y; }; 1.3定义结构类型 1.3. ...

  3. mfc添加自定义事件

    1.在对话框的头文件里面添加声明函数: afx_msg void OnStnClickedPicStop(); 2.在对话框的源文件添加 BEGIN_MESSAGE_MAP(CPcEn3dTestDl ...

  4. linux下安装nexus repository及Intellij Idea集成私有maven

    前段日子公司搞java项目,使用nexus repository搭建了私有maven库,现在把原来的私有nuget也迁到nexus repository上了,下面介绍下搭建流程: https://he ...

  5. 记录一次 “ORA-12516:TNS:监听程序找不到符合协议堆栈要求的可用处理程序” 的处理过程

    一.今天同事反馈业务化运行的数据中心库发生了oracle无法连接的情况,导致所有业务系统无法正常运作的问题.报:“ORA-12516:TNS:监听程序找不到符合协议堆栈要求的可用处理程序” 二.收到这 ...

  6. 基础总结(03)-- css有趣的特性

    1.currentColor:可用于background/border-color/渐变/box-shadow/svg填充色,颜色继承自color. 待补充…

  7. skynet框架之日程表设计

    参考云风大神的例子,对其进行了改进,支持多次提交单个日程,改变时间后,提前日程触发时间. --[[ t提供了两种方案 方案1和2 ]] local skynet = require "sky ...

  8. PackagesNotFoundError: The following packages are not available from current channels

    因为要用到lifelines 包,在cmd中使用conda install lifelines ,显示如下错误: PackagesNotFoundError: The following packag ...

  9. jinja2 把文本变成html

    data 是传过去的值 过滤器 | {{data.name | safe}}

  10. abp.net zero 运行报500.21,错误模块AspNetCoreModuleV2

    关于这个运行时提示的问题,导致项目无法运行,之前我是遇到过的,也是查了很久最后解决了 但忘记记录了...岁数大了脑袋不好用了...这次依然找了各种方案,有很多都说由于net core 不是最新的,但我 ...