Java NIO概述

来源:互联网 发布:淘宝轮播图的尺寸 编辑:程序博客网 时间:2024/05/04 23:55

概述

JAVA NIO是IO复用模型( POSIX定义的五种IO模型: 阻塞IO, 非阻塞IO, IO复用, 异步IO, 信号驱动IO )的实现.

在Linux系统中,复用IO用三种实现: select, poll, epoll.

select

select实现有2个问题,文件描述符的限制以及需要对所有监听的channel进行遍历

poll

poll实现解决的是描述符限制, 依然还需要进行channel遍历

epoll

epoll解决了遍历channel的问题, 通过向内核注册事件, 当有监听事件发生时, 可以准确知道是哪个channel

复用IO本质上还是阻塞的, 内核读取到数据后, 用户进程从内核进程中拷贝数据的过程是同步阻塞的. IO模型中的异步I是完全异步的, 内核会将数据拷贝到用户进程后, 才会通知用户进程.

Selector

Java文档中描述Selector:

A multiplexor of SelectableChannel objects.

可以理解为SelectableChannel对象的多路复用实现.Channel(SelectableChannel)可以通过Selector实现多路复用.

java.nio中定义了一个Selector类,可以通过其open()静态方法获取Selector实例.
还有另外一种机制是通过SelectorProvider自定义实现获取selector, SelectorProvider是通过SPI机制动态发现其实现类.

Buffer

Buffer是一个数据缓冲区, 属于堆外内存, 不属于在JVM运行时内存模型.

Java文档中描述Buffer:

A container for data of a specific primitive type.

可以理解为基本类型数据的容器。

在输入的时候, Buffer是Channel的输入源, 在输出的时候, Buffer是输出源.

java.nio中实现多种基本类型的Buffer(ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer).

当类型是ByteBuffer的时候, 要注意编码的问题.

Channel

Java文档中对Channel的描述是:

A nexus for I/O operations.

可以理解为 IO操作的一个纽带.

java.nio.channels.SelectableChannel 定义了Channel可以通过selector实现多路复用.

DatagramChannel, Pipe.SinkChannel, Pipe.SourceChannel, ServerSocketChannel, SocketChannel
这几个类是其子类(实际是AbstractSelectableChannel的直接子类),也就是说这几个类型的channel可以实现多路复用.然而FileChannel不在其中, 也就是磁盘IO不能实现多路复用.

那么问题来了, FileChannel为什么不能实现多路复用?既然不能实现IO复用, 为何又要提供一个FileChannel的类呢?

参考资料

  • NIO系列
0 0