NIO Buffer capacity(容量)、position(读写位置)和 limit(读写的限制)

1. capacity 属性

Buffer 类的 capacity 属性表示内部容量的大小。一旦写入的对象数量超过了 capacity,缓冲区就满了,不能再写入了。

Buffer 类的 capacity 属性一旦初始化,就不能再改变。原因是什么呢?Buffer 类的对象在初始化时会按照 capacity 分配内部数组的内存,在数组内存分配好之后,它的大小就不能改变了。

前面讲到,Buffer 类是一个抽象类,Java 不能直接用来新建对象。在具体使用的时候,必须使用 Buffer 的某个子类,例如 DoubleBuffer 子类,该子类能写入的数据类型是 double,如果在创建实例时其 capacity 是 100,那么我们最多可以写入 100 个 double 类型的数据。

说明

capacity 并不是指内部的内存块 byte[]数组的字节数量,而是指能写入的数据对象的最大限制数量。

2. position 属性

Buffer 类的 position 属性表示当前的位置。position 属性的值与缓冲区的读写模式有关。在不同的模式下,position 属性值的含义是不同的,在缓冲区进行读写的模式改变时,position 值会进行相应的调整。

在写模式下,position 值的变化规则如下:

(1)在刚进入写模式时,position 值为 0,表示当前的写入位置为从头开始。

(2)每当一个数据写到缓冲区之后,position 会向后移动到下一个可写的位置。

(3)初始的 position 值为 0,最大可写值为 limit-1。当 position 值达到 limit 时,缓冲区就已经无空间可写了。

在读模式下,position 值的变化规则如下:

(1)当缓冲区刚开始进入读模式时,position 会被重置为 0。

(2)当从缓冲区读取时,也是从 position 位置开始读。读取数据后,position 向前移动到下一个可读的位置。

(3)在读模式下,limit 表示可读数据的上限。position 的最大值为最大可读上限 limit,当 position 达到 limit 时表明缓冲区已经无数据可读。

Buffer 的读写模式具体如何切换呢?当新建了一个缓冲区实例时,缓冲区处于写模式,这时是可以写数据的。在数据写入完成后,如果要从缓冲区读取数据,就要进行模式的切换,可以调用 flip()方法将缓冲区变成读模式,flip 为翻转的意思。

在从写模式到读模式的翻转过程中,position 和 limit 属性值会进行调整,具体的规则是:

(1)limit 属性被设置成写模式时的 position 值,表示可以读取的最大数据位置。

(2)position 由原来的写入位置变成新的可读位置,也就是 0,表示可以从头开始读。

3. limit 属性

Buffer 类的 limit 属性表示可以写入或者读取的数据最大上限,其属性值的具体含义也与缓冲区的读写模式有关。在不同的模式下,limit 值的含义是不同的,具体分为以下两种情况:

(1)在写模式下,limit 属性值的含义为可以写入的数据最大上限。在刚进入写模式时,limit 的值会被设置成缓冲区的 capacity 值,表示可以一直将缓冲区的容量写满。

(2)在读模式下,limit 值的含义为最多能从缓冲区读取多少数据。

一般来说,在进行缓冲区操作时是先写入再读取的。当缓冲区写入完成后,就可以开始从 Buffer 读取数据,调用 flip()方法(翻转),这时 limit 的值也会进行调整。具体如何调整呢?将写模式下的 position 值设置成读模式下的 limit 值,也就是说,将之前写入的最大数量作为可以读取数据的上限值。

Buffer 在翻转时的属性值调整主要涉及 position、limit 两个属性,但是这种调整比较微妙,不是太好理解,下面举一个简单的例子:

首先,创建缓冲区。新创建的缓冲区处于写模式,其 position 值为 0,limit 值为最大容量 capacity。

然后,向缓冲区写数据。每写入一个数据,position 向后面移动一个位置,也就是 position 的值加 1。这里假定写入了 5 个数,当写入完成后,position 的值为 5。

最后,使用 flip 方法将缓冲区切换到读模式。limit 的值会先被设置成写模式时的 position 值,所以新的 limit 值是 5,表示可以读取数据的最大上限是 5。之后调整 position 值,新的 position 会被重置为 0,表示可以从 0 开始读。

缓冲区切换到读模式后就可以从缓冲区读取数据了,一直到缓冲区的数据读取完毕。

除了以上 capacity、position、limit 三个重要的成员属性之外,Buffer 还有一个比较重要的标记属性:mark(标记)属性。该属性的大致作用为:在缓冲区操作过程当中,可以将当前的 position 值临时存入 mark 属性中;需要的时候,再从 mark 中取出暂存的标记值,恢复到 position 属性中,重新从 position 位置开始处理。

转自 Java高并发核心编程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值