buffer A container for data of a specific primitive type.
除了本身存储的数据之外,最重要的属性是 capacity,limit 和 position
capacity: buffer的容量,,不会是负数也不会改变
limit:第一个不能被读取或写入的索引,不会是负数,也不会超过容量
position:下一个将要被读取或者写入的索引,不会超过limit
buffer是可读可写的。。。。
There is one subclass of this class for each non-boolean primitive type. 没有bool类型的buffer,其余原生类型的都有
每个子类有两个get set 操作
相对操作:读写操作在当前的position位置上增加,如果超过limit抛出异常
绝对操作:会指定一个指定的索引进行操作,不会影响本身的position位置
channel通常会根据当前position的位置来操作buffer里的数据。
Mark标记position已经操作过的位置,通过remark方法可以重新让position回到mark的位置。
如果调整position或者limit的索引小于mark的位置,mark或被清楚,值变为-1
如果没有mark或者调用remark抛异常
新创建的buffer position 为0,mark为-1,limit可能是0或者其他值。每一个元素的初始化值为0
clear:position为0.limit为capacity 效果:清空buffer
flip:limit为当前position,position为0 效果:转换buffer的读写状态
rewind:limit不改变,position为0 效果:重新读或者写
只读的buffer:buffer内的每个元素不允许改变,但是mark,position和limit的值可以改变。可以调用isReadOnly设置一个buffer是不是只读的buffer
buffer不是线程安全的
可以使用方法链 例如:
b.flip().position(23).limit(42);
堆内内存
直接内存也是堆外内存
区别:顾名思义,内存是在jvm的堆中还是堆外的内存中。
MappedByteBuffer:
一个文件的内存映射区域。堆外内存
将文件信息读取到内存,通过对内存的操作,直接影响到磁盘上的文件
如果文件某个时刻被截断了或者发生其他变化,那么内存映射区域就不可访问了。所以程序读写之外的操作要小心!否则会抛出异常。
这个映射的内存可能在任何时刻都会被当前的程序或者其他程序改变。
scattering 和 gattering:
可以定义多个buffer,指定不同的大小来读取不同的信息。可以将一个数据分解到不同buffer,方便后续操作。
selector:
可选择channel对象的多路复用器!
可以通过.open()方法来创建一个selector,这种方式使用的是系统默认的selector provider。也可以通过特定的selector provider的openSelector方法来创建。
一个selectable channel注册到selector上通过SelectionKey这个对象来表示。
selector有3套SelectionKey
key set 包含了selector当前所有已经注册的channel 通过keys()方法获取 selected-key set 每个channel都会有自己interest key来表示这个channel要做什么事情,比如读写操作,或者接收连接/发起连接操作。 在一次select操作后,这些key代表的channel已经准备好将要执行了。 通过selectedKeys()方法调用。 cancelled-key 调key已经被取消了,但是channel还没有从selector上取消。
selected-key 和 cancelled-key 都是keyset 的子集
新创建的selector这三种集合都是空的。
通过channel的 register(Selector,int) 方法注册到selector的同时也会将一个key注入到selector的key set中。
无论是关闭channel或者是调用selection的cancel方法,这个key都会被添加都cancelled-key set中
selection 操作会将key添加到selected-key中。可以通过set的remove方法或iterator的remove方法直接从selected-key中移除。不会有其他的形式。
每一次的selection操作selected-key set中都会有key被添加或被移除,cancelled-key set或者key set中都有可能移除key。
selection操作包含三个部分:
将cancelled-key set中的key从key set中移除。这样cancelled-key set也就是个空集了。
查询底层的操作系统是否有channel已经准备好要执行它感兴趣的操作了。这个操作分为两种表现形式:如果这个channel不在selected-key set中,那么将他加入进来,并将他的就绪状态修改。如果在selected-key set中,那么就直接修改就绪状态。
如果在第二步执行的时候有key被添加到了cancelled-key,那么直接按照步骤一执行。