最近由于业务需要,写了一个 java server用来与我们的游戏服务器实现交互。
server只实现了最基本的功能: 维护多个长连接,发送与接收消息;连接建立及断开(主动与被动)。
在实现的过程中,最有意思的是java nio里的buffer,但我认为这是一个失败的设计。
java nio buffer三个主要的属性,position, limit, capacity.
通常来讲,传统的ringbuffer都会有一个read index和write index, 但buffer nio将两者统一为postion,然后弄出了读写模式切换的概念。
当从buffer里取出数据,即buffer.getXXX或者channel.write(buffer),
当往buffer里放入数据,即buffer.putXX或者channel.read(buffer),
的前后,经常要考虑模式的切换,比如调用flip,这样的设计增加了复杂性,对库的使用者带来困难(笔者才疏学浅,一直疑惑他们为什么这么设计,求高人指教),这本质上是因为position属性既要当作readindex来使用,又要当作writeindex来使用。
另外一点就是由于postion的大小不能超过limit和capacity, 导致使用的过程中经常需要compact, 每次compact会导致额外的内存拷贝;传统的ringbuffer会在writeindex < readindex在的时候才可能涉及到额外内存的拷贝。
也难怪,netty里抛弃了这种设计。