当前位置: 首页 > HadoopJava > 深入解析MapReduce架构设计与实现原理–读书笔记(8)hadoop NIO

深入解析MapReduce架构设计与实现原理–读书笔记(8)hadoop NIO

J2SE1.4以后,java发布了新的IO类库,简称NIO。引入了全新的高效的IO机制,同时引入了基于Reactor设计模式的多路复用异步模式。

包含以下几种抽象数据类型

Channel(管道)

NIO把它支持的IO对象抽象为channel。它模拟了通信连接,类似于IO中的stream。用户可以通过它读取和写入数据。
SocketChannel,ServerSocketChannel,FileChannel,DatagramChannel等。

Buffer(缓冲区)

Buffer是一块连续的内存区域,一般作为channel收发数据的载体出现。所有数据都通过Buffer对象来处理。用户永远不会将字节直接写入channel中。
相反,需要将数据写入包含一个或者多个字节的缓冲区;同样,也不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

Selector(选择器)

Selector类提供了监控一个或者多个channel当前状态的机制。只要Channel向Selector注册了某种特定事件,Selector就会监听这些事件是否会发生,一旦发生某个事件,
便会通知对应的Channel。

常用类

1.Buffer相关类

java.nio包公开了Buffer API,可以直接控制和运用缓冲区。所有缓冲区包含以下3个属性
capacity:缓冲区的末位值。它表明了缓冲区最多可以保存多少数据。
limit:表示缓冲区的的那个钱存放数据的终点,不能对超过limit的区域进行读写操作
position:下一个读写单元的位置。每次读写缓冲区时,均会修改该值,为下一次读写数据做准备。
capacity>=limit>=position>=0
buffer有2种工作模式:写模式和读模式。
写模式下,limit与capacity相同,position随着写入数据增加,逐渐增加到limit,因此,0到position之间的数据即为已经写入的数据。
读模式下,limit初始指向position所在位置,position随着数据的读取,逐渐增加到limit,则0到position之间的数据即为已经读取的数据。
flip() 可将写模式转换为读模式
clear() 重置Buffer,即将limit设为capacity,而position为0
hasRemaining()/remaining() 分别用于判断Buffer是否有剩余空间和获取Buffer剩余空间。剩余空间大小为capacity – position
capacity()/limit()/position() 分别用于获取属性值。
limit(int newLimit)/position(int newPosition) 分别用于设置Buffer的limit和position属性。
java.nio.buffer是一个抽象类,不能被实例化。每种基本类型都有对应的具体的Buffer类(除boolean)。其中最基本的是ByteBuffer。它存放的数据单元是字节。
它并没有提供直接的构造函数,而提供了静态方法。
//创建一个Heap Buffer,其空间分配在JVM的堆上,由GC回收。
static ByteBuffer allocate(int capacity) ;
//创建一个Direct Buffer,通过底层的JNI调用C Runtime Time的malloc函数分配空间,可看作内核空间。创建代价大,但是比Heap Buffer更高效。
static ByteBuffer allocateDirect(int capacity);

2.channel相关类

java.nio提供了多种Channel实现,其中,最常用的是以SelectableChannel为基类的通道。支持阻塞IO与非阻塞IO。
//设置当前SelectableChannel的阻塞模式;block表示是否将SelectableChannel设置为阻塞模式;返回SelectableChannel对象本身的引用。
SelectableChannel configureBlocking(boolean block) throws IOException
//将当前Channel注册到一个Selector中,sel表示要注册的Selector,ops表示注册事件。
//ops包括:OP_READ,OP_ACCEPT,OP_WRITE,OP_CONNECT
SelectionKey register(Selector sel,int ops) throws ClosedChannelException
包含2个子类
ServerSocketChannel,SocketChannel,他们分别是ServerSocket和Socket的替代类。
ServerSocketChannel用于监听TCP连接
ServerSocketChannel open() throws IOException;//创建ServerSocketChannel的静态工厂方法。
SocketChannel accept() throws IOException;//接收来自客户端的连接。一旦有客户端请求出现,则会返回一个处于阻塞模式的SocketChannel
ServerSocket socket() 返回一个与ServerSocketChannel关联的ServerSocket对象。
SocketChannel可以看作Socket的替代类。
boolean connect(SocketAddress remote) throws IOException //连接Channel对应的Socket。如果SocketChannel处于阻塞状态,直接返回结果;否则,进入阻塞状态。
//将当前channel中的数据读取到ByteBuffer中。在非阻塞模式中,能读取到多少数据就读取多少的原则,总是立即返回结果;
//在阻塞模式下,将尝试一直读取数据,知道ByteBuffer被填满,到达输入流末尾或者抛出异常。该函数的返回值为实际读取的数据字节数。
int read(ByteBuffer dst) throws IOException
//将ByteBuffer中的数据写入Channel中。与read函数类似。
//在非阻塞模式下,能输出多少数据就输出多少的原则,总是立即返回结果;
//在阻塞模式下,会尝试将所有数据写入channel。
int write(ByteBuffer src) throws IOException

3.Selector类

Selector可监听ServerSocketChannel和SocketChannel注册的特定事件,一旦某个事件发生,则会通知对应的Channel。SelectableChannel的register方法负责注册事件。
该方法返回一个SelectionKey对象,该对象即为用于跟踪这些注册事件的句柄。
//静态工厂,创建Selector对象。
static Selector open()
//该方法等待并返回发生的事件。一旦某个注册的事件发生,就会返回对应的SelectionKey的数目。
int select(long timeout)
//Selector捕获的已经发生事件对应的SelectionKey集合。
set SelectedKeys()

4.SelectionKey类

ServerSocketChannel或SocketChannel通过register()方法向Selector注册事件时,regsiter方法就会创建一个SelectionKey对象,用于跟踪注册事件。
SelectionKey.OP_ACCEPT:接收连接就绪事件,表示服务器端接收到了客户端连接。
SelectionKey.OP_CONNECT:连接就绪事件,表示客户端与服务器端的连接已经建立成功。
SelectionKey.OP_READ:读就绪事件,表示通道中已经有了可读数据,可执行读操作了。
SelectionKey.OP_WRITE:写就绪事件,表示可向通道中写入数据了。
通常,ServerSocketChannel对象向Selector中注册OP_ACCEPT事件;SocketChannel对象向Selector中注册OP_CONNECT,OP_READ,OP_WRITE三种事件。
//为当前SelectionKey关联一个Object类型的对象。每个SelectionKey只能关联一个对象。
Object attach(Object obj);
//获取当前SelectionKey关联的Object对象
Object attachment();
//返回与当前SelectionKey关联的SelectableChannel对象
SelectableChannel channel();



本文固定链接: http://anyoneking.com/archives/734 | 懒散狂徒的博客
标签: , , , , , , , , , ,

【上一篇】
【下一篇】

报歉!评论已关闭.