最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结。

简介

NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO方式NIO采用了全新的底层I/O模型。传统IO的设计概念是面向流,而NIO则是面向块。简单点说,传统I/O是基于字节的,所有I/O都被视为单个字节的移动,使用时需先把对象转换为字节码;而NIO是面向块的,以块为单位处理数据,每个操作会生成或消费一个块的数据。从设计理念来看,NIO的操作粒度要比传统IO大很多,采用这种方式性能有很大提高,但也牺牲了java操作的优雅和简洁。

核心模块

Java NIO 由以下三个核心模块组成:

  • Selector
  • Channel
  • Buffer

Selector

线程的花销很大,selector帮助开发者突破IO的瓶颈,它提供了单线程处理多个 Channel的机制。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。

这是在一个单线程中使用一个Selector处理3个Channel的图示:

要使用Selector,得先向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。

使用Selector,先得向Selector注册Channel,然后调用它的select()方法,这个方法会一直阻塞直到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件。

Channel

Channel是一个对象,可以通过它读取和写入数据,所有的IO在NIO中都从一个Channel 开始。Channel中的数据要么写入Buffer,要么从Buffer读取。拿 NIO 与原来的 I/O 做个比较,Channel就像是流。所有数据都通过Buffer对象来处理,NIO不会将字节直接写入通道中,相反,它是将数据写入包含一个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。
通道与流的不同之处在于通道是双向的,而流只是在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类), 而 通道可以用于读、写或者同时用于读写。因此,通道可以比流更好地反映底层操作系统的真实情况。特别是在UNIX模型中,底层操作系统通道是双向的。

常用的Channel:

  • FileChannel:File
  • DatagramChannel:UDP
  • ScoketChannel:TCP
  • ServerSocketChannel:监听TCP连接

Buffer

Buffer与Channel的关系如下图:

Buffer也是NIO的一个亮点,传统的IO操作面向数据流,意味着每次从流中读一个或多个字节,直至完成,数据没有被缓存在任何地方。NIO操作面向缓冲区,数据从Channel读取到Buffer缓冲区,随后在Buffer中处理数据。

Buffer其实就是一块缓存区,内部使用字节数组存储数据,并维护几个特殊变量,实现数据的反复利用。

目前Buffer的实现类有以下几种:

  • ByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer
  • MappedByteBuffer

这些都是抽象类,针对各自的应用场景,下面又有很多子类,功能强大。

思考总结

一般我们在工作中遇到NIO相关的场景时,大多都有封装好的三方库,但并不是说就没必要了解其实现原理,知其然而不知其所以然用着也会心虚。

另外,学习优秀的开源项目是提升个人能力的一个有效方法,研究源码可以从以下几个点入手(个人认为):

    • 架构文档 (在脑中建立框架图)
    • 示例代码与单元测试(知道具体接口使用细节)
    • 具体模块实现代码(数据结构 - public方法 - private方法)

JAVA NIO学习笔记1 - 架构简介的更多相关文章

  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 ...

随机推荐

  1. make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl] 错误 1,make: *** [out/host/linux-x86/obj/lib/libESR_Portable.so] 错误 1

    错误3: g++: g++: selected multilib '32' not installed selected multilib '32' not installed make: *** [ ...

  2. JavaScript中的事件对象

    JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...

  3. WCF服务跟踪

    如果在开发过程中,WCF服务出现问题,我们可以通过服务引用,然后直接断点调试进去.然而,对于已经发布的服务,出现错误时,寻找错误信息会变得麻烦. 幸好,微软提供了服务跟踪查看器工具 (SvcTrace ...

  4. SPFA+Dinic HDOJ 3416 Marriage Match IV

    题目传送门 题意:求A到B不同最短路的条数(即边不能重复走, 点可以多次走) 分析:先从A跑最短路,再从B跑最短路,如果d(A -> u) + w (u, v) + d (B -> v) ...

  5. 微信支付之h5方式(非微信内置浏览器中支付)

    这两天完成了公司网站手机和PC端的支付对接,就是支付宝和微信. 对接完后有所感触,我们来聊一聊,微信支付的坑,为什么这么说呢,因为我在对接完支付宝后是很愉快的,基本上在demo上稍加修改就ok了, 对 ...

  6. Python 判断是否为质数或素数

    一个大于1的自然数,除了1和它本身外,不能被其他自然数(质数)整除(2, 3, 5, 7等),换句话说就是该数除了1和它本身以外不再有其他的因数. 首先我们来第一个传统的判断思路: def handl ...

  7. Shell编程基础篇-下

    1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 -f文件,f的全拼为file ...

  8. 使用Web Audio API绘制音波图

    摘要:Web Audio API是对<audio> 标签功能上的补充,我们可以用它完成混音.音效.平移等各种复杂的音频处理,本文简单的使用其完成音波图的绘制. PS:本例子使用ES6编程, ...

  9. HDU ACM 1879 继续畅通工程

    继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  10. PAT A1145 Hashing - Average Search Time (25 分)——hash 散列的平方探查法

    The task of this problem is simple: insert a sequence of distinct positive integers into a hash tabl ...