前言
Github:https://github.com/yihonglei/jdk-source-code-reading(java-nio)
一 概述
Java NIO 全称 java non-blocking IO,是 JDK1.4 及以上版本里提供的可以替代标准 Java IO API 的新 IO API(New IO),
为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。
Java NIO 提供了与标准 IO 不同的 IO 工作方式。Java NIO 由以下几个核心部分组成:
- Channels(通道)
- Buffers(缓冲区)
- Selectors(选择器)
虽然Java NIO中除此之外还有很多类和组件,但是最主要的是Channel,Buffer和Selector构成了核心的API。
1、Channels 和 Buffers(通道和缓冲区)
标准的 IO 基于字节流和字符流进行读写操作的,而 NIO 是基于通道(Channel)和缓冲区(Buffer)进行读写操作,
数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。所有的 IO 在 NIO 中都从一个 Channel 开始。
拿 NIO 与原来的 IO 做个比较,通道就像是流,而且他们面向缓冲区(Buffer)的。通道与流的不同之处在于通道是双向的。
而流只是在一个方向上移动。数据可以从 Channel 读出到 Buffer 中,也可以从 Buffer 写到 Channel 中,
即通道可以用于读、写或者同时用于读写。如图:
Channel和Buffer有好几种类型。
Java NIO中主要的Channel实现
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
这些通道涵盖了 UDP 和 TCP 网络 IO,以及文件 IO。
Java NIO 中主要的 Buffer 实现
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
- MappedByteBuffer
这些 Buffer 覆盖了你能通过 IO 发送的基本数据类型:byte、short、int、long、float、double和char。
Non-blocking IO(非阻塞IO)
Java NIO 可以让你非阻塞的使用 IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。
当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。
2、Selectors(选择器)
Java NIO 引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。
因此,单个的线程可以监听多个数据通道。Selector 允许单线程处理多个 Channel。
如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用 Selector 就会很方便。
例如,在一个聊天服务器中。这是在一个单线程中使用一个 Selector 处理3个 Channel 的图示:
要使用 Selector,得向 Selector 注册 Channel,然后调用它的 select() 方法。
这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,
线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。