偶然在网上浏览到这样的一些字眼“写一个自己的RPC框架”,心中也很激愤。于是乎想从头开始,深入研究一下如何搭建一个RPC框架。笔者是做java的,市面上开源的RPC框架很是不少,Dubbo、Thrift等等。我规划了一下自己的算是学习路线。线程->nio->netty->RPC->RPC产品。线程相关的知识笔者自认为还算可以。那么就从nio开始,很多人认为应该先从“同步”“异步”“阻塞”“非阻塞”几个概念开始,但是这些网上解释的已经很是透彻,就从nio涉及的几大成员开始吧,第一站:Buffer。
一 、Buffer
一种byte数组类型的存储结果。
抽象类
非线程安全
具有6个属性,其中
mark:标示位,默认为-1。一般配合mark和reset一起用,下面再说。
position:默认为0,表示当前可操作元素的位置。
limit:数据指针可到达的最大位置。
capacity:总容量
address:直接内存buffer中会用到,之后说。
属性值之间的关系 :mark <= position <= limit <= capacity
方法
均有获取以上属性值 带参和不带参的方法,不带参为获取当前数组中的值,带参则是指定值。
mark(): 将当前的mark值设置为position的值。
reset(): 将position的值设置为当前mark的值。
clear():初始化所有属性值为默认值。
flip():limit的值设置为position的值,其他属性值设置为默认的值。
rewind():读/写到buffer中数据,然后调用rewind 从来再开始。position=0 mark=-1.
remaining():剩余可操作容量 limit-position
hasRemaining():是否还有剩余 limit-position>0?
isReadOnly():
isDirect():
nextGetIndex() 带参(返回position+int参数的位置)和不带参(返回当前position的位置)两种。
checkIndex(int i) 检测给定的值i 是否在可操作范围内。
discardMark() 将mark属性值设置为默认值 也就是-1
truncate() mark=-1 其他值为0
buffer类及其子类的所有操作方法 都仅仅是操作几个属性的值 对里面的元素没有任何操作,简单的说,只是指针的变化,但是元素没有任何变动。我没有列出源码,我相信所有人的机器上都会有的。
二、HeapByteBuffer& HeapByteBufferR
堆内内存,jvm堆内内存,垃圾回收由jvm来控制。
ByteBuffer.allocate(int) 分配内存。
方法
slice(): 构造一个与源buffer共享元素的buffer ,mark=-1,position=0,limit=capacity=源buffer的remaining也就是剩余长度,offset=position+offset。也就是说,如果是正常遍历而改动的数据指针属性值的话,这个操作是将所有remaining的位置构成一个新的共享同一些元素的buffer。
duplicate():复制一份源buffer 构成一个新buffer,共享元素。
asReadOnlyBuffer() 复制一份源buffer,构成一个只读buffer(HeapByteBufferR.class)
ix(int i): 相对offset 第i个元素。 offset默认为0;
get() = hb[ix(nextGetIndex())] 获取当前相对offset位置第 position的元素。
get(i) 获取指定位置的元素,首先i需要在可操作元素的下标范围内。
get(byte[] arg,offset,length) 将buffer中的元素,copy到arg中。
put(byte[] arg,offset,length) 将arg中的元素,copy到buffer中。
compact():从当前position位置开始向后取remaining()长度的元素,放到buffer 从position=0开始的位置。置换完成之后,position=remaining() mark=-1
HeapByteBufferR只读buffer,重写了所有写操作,均会抛出异常,通过buffer.asReadOnlyBuffer()来构建。
关于方法使用的具体业务场景,现在能写出来的都是个人猜测,所以我想在接下来的测试中补全。