文章插图
Java NIO里关键的Buffer实现:
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
为了理解Buffer的工作原理 , 需要熟悉它的三个属性:
- capacity
- position
- limit
文章插图
capacity
作为一个内存块 , Buffer有个固定的最大值 , 就是capacity 。Buffer只能写capacity个byte、long、char等类型 。一旦Buffer满了 , 需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据 。
position
当写数据到Buffer中时 , position表示当前的位置 。初始的position值为0 。当一个byte、long等数据写到Buffer后 , position会向前移动到下一个可插入数据的Buffer单元 。position最大可为capacity – 1.
当读取数据时 , 也是从某个特定位置读 。当将Buffer从写模式切换到读模式 , position会被重置为0 。当从Buffer的position处读取数据时 , position向前移动到下一个可读的位置 。
文章插图
limit
在写模式下 , Buffer的limit表示最多能往Buffer里写多少数据 。写模式下 , limit等于capacity 。
当切换Buffer到读模式时 , limit表示你最多能读到多少数据 。因此 , 当切换Buffer到读模式时 , limit会被设置成写模式下的position值 。
Selector
Selector允许单线程处理多个 Channel 。如果你的应用打开了多个连接(通道) , 但每个连接的流量都很低 , 使用Selector就会很方便 。例如 , 在一个聊天服务器中 。
这是在一个单线程中使用一个Selector处理3个Channel的图示:
文章插图
要使用Selector , 得向Selector注册Channel , 然后调用它的select()方法 。这个方法会一直阻塞到某个注册的通道有事件就绪 。一旦这个方法返回 , 线程就可以处理这些事件 , 事件例如有新连接进来 , 数据接收等 。
NIO与epoll的关系
Java NIO根据操作系统不同 , 针对NIO中的Selector有不同的实现:
- macosx:KQueueSelectorProvider
- solaris:DevPollSelectorProvider
- linux:EPollSelectorProvider (Linux kernels >= 2.6)或PollSelectorProvider
- windows:WindowsSelectorProvider
-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider
JDK在Linux已经默认使用epoll方式 , 但是JDK的epoll采用的是水平触发 , 所以Netty自4.0.16起, Netty为Linux通过JNI的方式提供了native socket transport 。Netty重新实现了epoll机制 ,
- 采用边缘触发方式
- netty epoll transport暴露了更多的nio没有的配置参数 , 如 TCP_CORK, SO_REUSEADDR等等 。
- C代码 , 更少GC , 更少synchronized
NioEventLoopGroup → EpollEventLoopGroupNioEventLoop → EpollEventLoopNIOServerSocketChannel → EpollServerSocketChannelNioSocketChannel → EpollSocketChannelNIO处理消息的核心思路
结合示例代码 , 总结NIO的核心思路:
- NIO 模型中通常会有两个线程 , 每个线程绑定一个轮询器 selector , 在上面例子中serverSelector负责轮询是否有新的连接 , clientSelector负责轮询连接是否有数据可读
- 服务端监测到新的连接之后 , 不再创建一个新的线程 , 而是直接将新连接绑定到clientSelector上 , 这样就不用BIO模型中1w 个while循环在阻塞 , 参见(1)
- clientSelector被一个 while 死循环包裹着 , 如果在某一时刻有多条连接有数据可读 , 那么通过clientSelector.select(1)方法可以轮询出来 , 进而批量处理 , 参见(2)
推荐阅读
- 各行的祖师爷是谁 自古以来各行各业的祖师爷
- 控制器|龙吟师傅教你布局办公室来催桃花
- 民主小学教师教育随笔 小学教师教学随笔
- 阴阳师|阴阳师:钓鱼系统出现?外服又玩梗,玩家希望愚人节笑话成真
- 祁门红茶馨香世界茶叶香气大师百岁华诞
- LOL5.18金属大师改动 莫德凯撒最新出装加点 金属大师加点
- 架构师分享:RocksDB使用技巧之分布式存储扩容演进
- 电商网站架构探索之SOA
- 浅谈Javaweb经典三层架构和MVC框架模式
- 华为达芬奇架构和arm架构有什么区别?