Java NIO即Java Non-blocking IO(Java非阻塞I/O),因为是在Jdk1.4之后增加的一套新的操作I/O工具包,所以一般会被叫做Java New IO。NIO是为提供I/O吞吐量而专门设计,其卓越的性能甚至可以与C媲美。NIO是通过Reactor模式的事件驱动机制来达到Non blocking的,那么什么是Reactor模式呢?Reactor翻译成中文是“反应器”,就是我们将事件注册到Reactor中,当有相应的事件发生时,Reactor便会告知我们有哪些事件发生了,我们再根据具体的事件去做相应的处理。
程序的性能很大程度上是受到I/O限制的,所以有很多人会说程序的性能瓶颈就在I/O上也毫不为过。下面这张图显示了I/O对程序吞吐量的影响
由上图可见I/O对程序的吞吐率有着决定性的因素。
Java中旧的IO接口,对文件操作只能一个字节一个字节或一行一行的读,对Socket IO会阻塞,可以为每一个Socket创建一个Thread,但是这样的系统开销和资源浪费都太大,不是合理选择;而NIO对Socket IO可以实现非阻塞,可以用单线程管理多个通道,并且NIO有了缓冲区的概念,不管是File IO还是Socket IO都是在和Buffer相互读取,看下图
所以NIO可以先将通道数据读到缓冲区中再进行操作,避免了逐字节或逐行读取的性能开销。
NIO有三个核心模块:Selector(选择器)、Channel(通道)、Buffer(缓冲区),另外java.nio.charsets包下新增的字符集类也是nio一个重要的模块,但个人觉得不算是NIO的核心,只是一个供NIO核心类使用的工具类。
Selector允许单个线程处理多个Channel,相比旧的IO为防止阻塞而为每一个Channel创建一个Thread来说,性能高出非常多;只用SelectableChannel才能注册到Selector,单线程处理多个Channel如下图
将Channel注册到Selector中,轮询调用select(),这个方法会阻塞,当注册的某个通道准备好要进行IO操作时,这个便返回已选择键的个数,此时通过selectedKeys获得已选择的键,就可以进行相关的IO操作了;选择键(SelectionKey)是用来连接Selector和Channel,将在后续讲解。
Channel主要有:FileChannel、ServerSocketChannel、SocketChannel、DatagramChannel,这四种通道涵盖了文件IO、TCP套接字IO、UDP数据报IO。
Buffer主要有:ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer,涵盖了IO操作的基本数据类型。