陆小曼|Java IO,讲的实在是太好了,这篇( 十 )


下面总结一下操作系统中零拷贝的优点:
降低CPU的压力:避免CPU需要参与内核空间与用户空间之间的数据拷贝工作减少不必要的拷贝:避免用户空间与内核空间之间需要进行数据拷贝上面的图示可能并不严谨 , 对于你理解零拷贝会有一定的帮助 , 关于零拷贝的知识点可以去查阅更多资料哦 , 这是一门大学问 。
介绍完通道后 , 我们知道它是用于传输数据的一种介质 , 而且是可以双向读写的 , 那么如果放在网络IO中 , 这些通道如果有数据就绪时 , 服务器是如何发现并处理的呢?接下来我们去学习NIO中的最后一个重要知识点:选择器(Selector)
选择器(Selectors)选择器是提升IO性能的灵魂之一 , 它底层利用了多路复用IO机制 , 让选择器可以监听多个IO连接 , 根据IO的状态响应到服务器端进行处理 。 通俗地说:选择器可以监听多个IO连接 , 而传统的BIO每个IO连接都需要有一个线程去监听和处理 。
Selector选择器主要用于网络IO当中 , 在这里我会将传统的BIOSocket编程和使用NIO后的Socket编程作对比 , 分析NIO为何更受欢迎 。 首先先来了解Selector的基本结构 。
重要方法方法解析open()打开一个Selector选择器intselect()阻塞地等待就绪的通道intselect(longtimeout)最多阻塞timeout毫秒 , 如果是0则一直阻塞等待 , 如果是1则代表最多阻塞1毫秒intselectNow()非阻塞地轮询就绪的通道
在这里 , 你会看到select()和它的重载方法是会阻塞的 , 如果用户进程轮询时发现没有就绪的通道 , 操作系统有两种做法:
一直等待直到一个就绪的通道 , 再返回给用户进程立即返回一个错误状态码给用户进程 , 让用户进程继续运行 , 不会阻塞这两种方法对应了同步阻塞IO和同步非阻塞IO , 这里读者的一点小的观点 , 请各位大神批判阅读
Java中的NIO不能真正意义上称为Non-BlockingIO , 我们通过API的调用可以发现 , select()方法还是会存在阻塞的现象 , 根据传入的参数不同 , 操作系统的行为也会有所不同 , 不同之处就是阻塞还是非阻塞 , 所以我更倾向于把NIO称为NewIO , 因为它不仅提供了Non-BlockingIO , 而且保留原有的BlockingIO的功能 。
了解了选择器之后 , 它的作用就是:监听多个IO通道 , 当有通道就绪时选择器会轮询发现该通道 , 并做相应的处理 。 那么IO状态分为很多种 , 我们如何去识别就绪的通道是处于哪种状态呢?在Java中提供了选择键(SelectionKey) 。
选择键(SelectionKey)在Java中提供了4种选择键:
SelectionKey.OP_READ:套接字通道准备好进行读操作SelectionKey.OP_WRITE:套接字通道准备好进行写操作SelectionKey.OP_ACCEPT:服务器套接字通道接受其它通道SelectionKey.OP_CONNECT:套接字通道准备完成连接在SelectionKey中包含了许多属性


推荐阅读