零、前言

  这里整理摘录了我了解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. dubbo 在不同协议下携带上下文区别

    如果走原生的dubbo协议,RpcContext.getContext()里的attarchments和values 是能够在节点间传递的 但如果hessian协议,attarchments和valu ...

  2. python之路——26

    复习 1.python没有接口类,有抽象类, 通过abc模块 本质是用来做代码规范用的,在子类中实现和父类方法名完全一样的方法2.在java的角度看,是有区别的 java没有多继承,为了接口隔离原则, ...

  3. C# Directory.Exists() 文件存在但返回一直为false

    备注:这是一个低级错误,起始真正的原因不是访问权限的问题. 真正的原因是:这个程序要读取远程电脑上共享文件夹里的文件,但是没有远程访问代码,导致找不到相关的目录.所以才报错! 查询一个文件,但程序突然 ...

  4. [OutLook]关闭Outlook时最小化

    关闭Outlook时最小化 dll 11.首先把dll 文件复制到C:\Users\hetao\AppData\Roaming\Microsoft\AddIns 22.然后以管理员的方式运行cmd.e ...

  5. MacBook Home End

    For the Home command, press down the Fn + Left Arrow keystroke combination. For the End command, pre ...

  6. POJ1083 Moving Tables

    POJ1083 Moving Tables Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35297   Accepted: ...

  7. Linux进阶指令(重点)

    三.Linux进阶指令(重点) 1.df指令    作用:查看磁盘的空间 #df -h 选项:-h    表示以可读性较高的形式展示大小 2.free指令     作用:查看内存使用情况 #free ...

  8. vs 为什么使用#include "stdafx.h"

    原因:1.减少编译次数 2.减少不必要的处理 流程图: 这个跟宏定义#ifndef xx #define xx  coding here #endif //xx 区别在于: 宏定义是防止头文件重复包含 ...

  9. 艾奇学院:66个信息流广告和SEM学习网址资源大放送!

    01.CNZZ-UDplus 网址:udplus.umeng.com 说明:基于用户行为的精细化分析.运营平台,去研究研究,很多料! 02.黑眼圈管理后台 网址:www.not3.com 说明:二类电 ...

  10. windows环境下安装rabbitmq及配置可视化管理界面

    1.环境 windows7 64位 rabbitmq3.7.9 erlang10.22.先安装erlang,后安装rabbitmq.下载地址: rabbitmq http://www.rabbitmq ...