一、NIO的概述
1,NIO简介
- NIO是jdk4引入的api,可以替代标准的io流,NIO与原IO有同样的作用和目的。
- 传统的java.io包,交互方式是同步、阻塞的、在写入数据、读取动作完成前,线程会一直组塞、读写之间是可靠的线性顺序调用,好处是代码比较简单、直观,缺点则是IO效率和扩展性存在局限性,容易成为应用性能的瓶颈。
- NIO使用方式完全不同,NIO支持面向缓冲区,基于通道的IO操作,提供了更加高性能的数据操作方式,
- NIO分为三个主要的组成部分:Channel(通道)、Buffer(缓冲区)、Selector(选择器)
2,概念理解
- 同步:调用方法之后必须得到一个返回值。
- 异步:调用方法之后没有返回值,但是会有回调函数(这里可以理解成满足条件后执行的方法)。
- 阻塞:如果没有达到方法的目的,就会一致停在那里(等待)
- 非阻塞:不管方法有没有达到目的,都会直接往下执行(不等待)
3,NIO与IO的区别
- IO面向流,NIO是面向缓冲区
- IO是阻塞的,NIO是非阻塞的
- NIO使用选择器
二、Buffer(缓存区)
1、概述
- NIO中,所有的数据都是用Buffer处理的,它是NIO读写数据的中转池。
- Buffer是缓冲区对象,包含写入或者读取流数据的操作。
- 应用程序不能直接对 Channel 进行读写操作,而必须通过 Buffer 来进行,即 Channel 是通过 Buffer 来读写数据的。
- Buffer实质是数组,通常是字节数组,也可以是其他数组。但Buffer不仅是数组,重要的是它提供了对数据的结构化访问,还可以跟踪系统的读写进程。
2、Buffer主要分类
- ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer
3、创建方式
-static ByteBuffer allocate(int capacity) 分配一个新的字节缓冲区。
-static ByteBuffer allocateDirect(int capacity) 分配新的直接字节缓冲区。
-static ByteBuffer wrap(byte[] array) 将 byte 数组包装到缓冲区中。
4、常用方法
- put();存入数据到缓冲数组中
- capacity():缓冲数组的容量
- limit();第一个不能读或写入元素的index索引
- position();当前第一个能读或写入元素的index索引
- mark() 在此缓冲区的位置设置标记。
- reset() 将此缓冲区的位置重置为以前标记的位置 。
- get();获取缓冲区的数据。
- flip() 切换读取数据的模式,limit设置为当前position,position设置为0
- clear() 清空整个缓冲区,limit设置为capacity,position设置为0
三、Channel(通道)
1、概述
- Channel(通道):Channel是一个对象,可以通过它读取和写入数据,可以把它看做是IO中的流。
- Channel负责传输,buffer负责存取:数据都通过Buffer处理,不需要将字节写入Channel中,而是将数据写入Buffer中,通过Buffer在通道中传输;读取数据也是通过Channel获取Buffer,再从Buffer中获取字节数据。
- Channel是双向的,可以比流更好地反映出底层操作系统的真实情况,特别是在Unix模型中。底层操作系统通常都是双向的。
2、Channel与流的区别
- Channel是双向的,既可以读又可以写,而流是单向的
- Channel可以进行异步的读写
- 对Channel的读写必须通过buffer对象
3、主要分类
-FileChannel:从文件读取数据的
-DatagramChannel:读写UDP网络协议数据
-SocketChannel:读写TCP网络协议数据
-ServerSocketChannel:可以监听TCP连接。
4、需求:使用FileChannel复制文件
5、需求:使用SocketChannel实现客户端与服务器的访问。
四、Selector(选择器)
1、概述
- Channel : 通道 ,负责传输 类似: 铁轨
- Buffer: 缓冲区,负责读写数据 类似 : 火车
- Selector: 选择器,负责调度通道 类似: 指挥中心
- 选择器Selector是NIO中的重要技术之一,与SelectableChannel联合使用了非阻塞的多路复用,节省CPU资源,提供程序的运行效率.
2,流程理解
3.Selector的使用思路
-Selector是一个对象,可以注册多个Channel,监听各个Channel上发生的事件,并根据事件情况决定Channel的读写,从而达到多路复用的效果。
- 1、把通道注册到选择器上
- 2、选择器监听客户端的请求
- 3、选择器获取要访问的服务器通道
- 4、服务器通道来处理客户端的请求
4.Selector的使用步骤
- 1.如何创建一个Selector
- 2.注册Channel到Selector
5、需求:演示多路复用建立连接的过程
6、需求:演示多路复用客户端发送数据的过程
五、NIO2(AIO)
1、概述
- Java 7 中,NIO 升级为 NIO2,引入了异步非阻塞 IO方式,也有人叫它 AIO(Asynchronous IO)。异步 IO 操作基于事件和回调机制,可以理解为,调用操作,不会阻塞,当后台处理完成,操作系统会通知相应线程进行后续工作。
- NIO虽然提供了非阻塞的方法,但是NIO的IO行为还是同步的。对于NIO来说,我们的业务线程是在IO操作准备好时,得到通知,接着就由这个线程自行进行IO操作,IO操作本身是同步的。
- AIO不是在IO准备好时再通知线程,而是在IO操作完成后,再给线程发出通知。因此AIO是不会阻塞的,此时的业务逻辑将变成一个回调函数,等待IO操作完成后,由系统自动触发。
- 与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 即read/write方法都是异步的,完成后会主动调用回调函数。)
2.常见类
- AsynchronousSocketChannel 客户端使用的通道。
- AsynchronousServerSocketChannel AIO socket编程中,服务端通道。
- AsynchronousFileChannel。
- AsynchronousDatagramChannel
- CompletionHandler接口
本阶段 学习目标
u能够说出NIO的优点



