Java NIO基础篇

2 篇文章 0 订阅
1 篇文章 0 订阅

什么是NIO

java.nio全称java non-blocking IO(实际上是 new io),是指JDK 1.4 及以上版本里提供的新api(New IO) ,为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。

原有的 IO 是面向流的(Stream)、阻塞的,NIO 则是面向块的(Buffer)、非阻塞的。

  • 面向流的I/O 系统一次一个字节地处理数据。
  • 一个面向块(缓冲区)的I/O系统以块的形式处理数据。

阻塞与非阻塞:
阻塞与非阻塞是描述进程在访问某个资源时,数据是否准备就绪的的一种处理方式。当数据没有准备就绪时:

阻塞:线程持续等待资源中数据准备完成,直到返回响应结果。
非阻塞:线程直接返回结果,不会持续等待资源准备数据结束后才响应结果。

我们可以理解为Channel是两地点之间的铁路,而Buffer是行在其上的火车

Channel

Channel 和 IO中的Stream(流)差不多一个级别的。不过Stream是单向的,如:InputStream , OutputStream ,而Channel是双向的,既可以进行读也可以写操作。
主要有以下四种实现:

  • FileChannel 从文件中读取数据
  • DatagramChannel 通过UDP读取网络中的数据
  • SocketChannel 通过TCP读取网络中的数据
  • ServerSockerChannel 监听新进来的TCP连接,类似web服务

Buffer

缓冲区,实际是一个容器,是一个连续数组。Channel提供从文件、网络读取数据的渠道,但是读取和写入数据都要通过Buffer。
在这里插入图片描述
上面的图描述了一个客户端向服务端发送数据的过程。
客户端发送数据时,先将数据存入Buffer中,然后将Buffer中的数据写入通道。服务端接收数据从Channel读取到Buffer,在从Buffer中读取出数据。
在NIO中Buffer是一个顶层父类,是一个抽象类,常用子类有;
ByteBuffer,IntBuffer,CharBuffer,LongBuffer等等。

我们拿到一个缓冲区需要进行的操作自然是:将数据写入缓冲区(put)/读取缓冲区数据(get)

一般工作流程如下:

  • 写入数据到buffer
  • 调用flip方法
  • 从buffer中读取数据
  • 调用clear方法或者compact方法

Buffer分为读模式和写模式:
在这里插入图片描述
Buffer类维护了4个核心变量属性来提供关于其所包含的数组的信息。它们是:

  • 容量Capacity缓冲区能够容纳的数据元素的最大数量。容量在缓冲区创建时被设定,并且永远不能被改变。(不能被改变的原因也很简单,底层是数组嘛)
  • 在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。写模式下,limit等于Buffer的capacity。当切换Buffer到读模式时, limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。换句话说,你能读到之前写入的所有数据。
  • Position下一个要被读或写的元素的位置, Position会自动由相应的 get( )和 put( )函数更新。
    写数据时,初始的position值为0。当一个byte、long等数据写到Buffer后,position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity-1。读数据时,position也是从0开始,向前读取数据。写模式向读模式切换时,会将position重置为0
  • 标记Mark一个备忘位置。用于记录上一次读写的位置。

重要方法

  • flip方法:从写模式切换到读模式,position置为0,limit设置为之前写模式的position值。
  • rewind方法:将position设置为0,但limit不变
  • clear方法:position设置为0,limit设置为capacity的值
  • compact方法:将所有未读的数据拷贝到Buffer起始处,然后将position设到最后一个未读元素正后面。limit属性依然像clear方法一样设置成capacity.现在Buffer准备好了写数据,但是不会覆盖未读数据。
  • mark、reset方法:通过调用Buffer.mark()方法,可以标记Buffer的一个特定position。之后可以通过调用Buffer.reset方法恢复到这个position

Selector

Selector类是NIO的核心类,Selector能够检测多个注册的通道上是否有时间发生,如果有时间发生,便获取时间然后针对每个事件进行响应的相应处理。这样一来,只是一个单线程就可以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发生时,才会调用函数来进行读写,就大大减小了系统开销,不用为每个连接都创建一个线程,不用维护多个线程,并且避免了多线程之间的上下文切换导致的开销。

在这里插入图片描述

更加详细参考: 这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值