Java高效NIO之Java IO基础 to be continued...

Java中有两套IO模型,分别是传统IO和JDK1.4新引入的NIO(叫New IO或 Non-Blocking IO,后者更能体现它的设计理念)。
在传统IO模型中,IO是基于数据流(Stream)的,数据的输入和输出分别对应Input Stream和Output Stream。流数据只能逐字节的读取(或写入),直到所有数据读取(或写入)完毕,流数据只能单向的读取(或写入),无缓存区,无法对数据进行前后移动访问。
在NIO模型中,IO是基于Buffer(缓存块)的,从IO(读文件、Socket)接收的数据由系统先保存在一块Buffer中,程序通过管道(Channel)接到Buffer,可以把Buffer当作一个类数组进行操作,可以在Buffer中前后移动,可以读取也可以写入。

添加IO和NIO的类继承结构图

传统IO模式,在处理数据流过程中,线程处于阻塞状态,直到流处理(读取后写入)完毕,所以一个线程只能处理一个IO任务,如果IO未准备就绪无数据(或不可写)线程只能一直等待,直到可以有数据(或可写);
NIO模式,采用IO多路复用技术,使用选择器(Selector)监控一组IO,虽然Selector线程也处于阻塞状态,但一个线程可以同时处理多个IO任务,当IO就绪时,Selector返回就绪的IO并由程序进行处理。

Java高效NIO之Java IO基础 to be continued..._第1张图片

NIO核心设计

如上图所示,NIO的核心涉及3部分,分别未Selector、Channel和Buffer。

Selector

Selector是NIO多理复用的执行组件,系统在处理多个IO任务时,可以把每个IO任务以Channel的方式注册到Selector,通过Selector.select()统一监控向其注册的Channel的状态,select()方法会阻塞,直到其中有Channel的IO状态准备就绪有数据可读(或IO可写)时,select()返回就绪IO的Channel由程序处理相关事件。

Channel

Channel是NIO中数据处理的入口,每个Channel对应着一个IO的底层数据Buffer,负责对Buffer的写入或读取操作。根据IO类型不同,Java中提供了如下通用Channel实现。

  1. FileChannel:文件读写操作
  2. SocketChannel:TCP Socket连接
  3. ServerSocketChannel:TCP Socket服务器端,处理监听端口建立Socket的accept事件
  4. DatagramChannel:UDP连接

Buffer

Buffer本质上是一块连续的内存区域,提供数据缓存功能和Channel对数据的读写操作能力。NIO提供了 ByteBuffer / CharBuffer / DoubleBuffer / FloatBuffer / IntBuffer / LongBuffer / ShortBuffer Buffer类型,实现读Java基本类型的缓存支持。对Buffer的读写操作过程中,涉及3个关键参数,即postion、limit和capacity。其中position和limit在读/写操作时具有不同的意义,而capacity读写时都是表示Buffer的大小。Buffer初始处于写状态,通过flip可以进行读写状态切换。

Java高效NIO之Java IO基础 to be continued..._第2张图片

Capacity
Buffer是一个固定大小的内存缓存区,Capacity就表示其总长度。向Buffer写入的数据字节(byte/char/int/long等)总长度不能超过Capacity。当Buffer写满时,需要(读取)清空后才能继续写入。

Position
Position初始位置为0,当Buffer读写模式切换时,也会自动重置为0。
读取模式时,Position表示当前读取数据的位置,读取当前位置数据后,Position自动移到下一个可读位置,读取位置不能超过Limit。
写入模式时,Position表达当前写入数据的位置,在当前位置写入数据后,Position自动移到下一个写入位置,写入位置不能超过Capacity - 1。

Limit
读模式时,Limit表示Buffer中可读取数据长度,当Buffer从写模式切换到读模式时,Limit值等于写模式时的Position。
写模式时,Limit表示可写入数据总长度,其值等于Capacity - 1。

你可能感兴趣的:(nio,channel,selector)