Java NIO学习与记录(一):初识NIO
工作中有些地方间接用到了
Ntty
,Netty是一个NIO框架,对于NIO却不是那么熟悉,这个系列的文章是我在学习NIO时的一个记录,也期待自己可以更好的掌握NIO。
一、NIO是什么?
一组由操作系统提供的底层API,java支持对它们的封装,我们需要做的是利用java来使用它们。非阻塞式IO与传统的阻塞式IO(BIO)不同,NIO可以通过通道(Channels
)来监听各通道的动作,一个线程就可以完成对多个通道的动作监听,这些动作包括连接就绪、写就绪、读就绪等,举个例子,建立连接这个动作在BIO中会发生阻塞,直到连接建立完成,而在NIO中,建连只是单线程里Selector
监听的一个动作,也就是说在建立连接之前(即建连就绪之前),这个线程是可以继续处理其他动作的(比如读、写等等)。没有BIO在交互时阻塞业务线程的现象,仅通过一个线程来处理n多IO通道(Channels
),大大提升了程序的处理能力。
二、NIO核心组成部分
2.1:Channels & Buffer
这两个放在一起讲,Channel
是指各种IO通道
(包括File
、Socket
等),也可以理解为双向IO流
,即:Channel既可以将自己的内容读到Buffer
中,也可以从Buffer中读取数据写入到自己里面。其次,Channel并不一定是双向的,一个Channel如果实现定义read()
方法的 ReadableByteChannel
接口,而另一个 Channel 类也许实现 WritableByteChannel
接口以提供write()
方法。实现这两种接口其中之一的类都是单向的,只能在单个方向上传输数据。如果一个类同时实现这两个接口,那么它是双向的,可以双向传输数据(读&写)。
结合上面描述,Buffer是一个容器,负责存储从Channel里读到的数据或者存储准备写入Channel的数据,属于一个缓冲区。
常见的Channel:
FileChannel:文件通道
DatagramChannel:一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数据包
SocketChannel:一个连接到TCP网络套接字的通道
ServerSocketChannel:一个可以监听新进来的TCP连接的通道
常见的Buffer:
ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer
可以发现,涵盖了基本传输的数据类型。
2.2:Selector
可以理解为“Channel事件选择处理器”,第一部分有提到说NIO属于非阻塞式IO,关键点在于Selector
可以运行于一个单线程里,然后通过一个死循环(阻塞方法)来监听注册到选择器内的Channel的事件(注意这里,一个Channel的事件想要被选择器监听到,则要求该Channel必须注册到选择器里),这些事件上面也提到过包含:连接就绪、写就绪、读就绪等。这些动作全部由Channel自己完成,什么时候完成了通知选择器去进行相应的逻辑处理即可,而不必阻塞在IO交互上(也是与传统BIO不同的点),选择器工作如下图:
本篇简单介绍了下NIO,接下来将会介绍具体如何去使用