jdk的Selector源码分析(一)Selector概述
2016-08-16 18:11
459 查看
1系列内容
jdk Selector设计情况jdk nio poll在linux平台下的实现
jdk nio epoll在linux平台下的实现
netty 原生epoll在linux平台下的实现
epoll的2种通知模式边缘触发、水平触发
2 jdk Selector概述
首先来看下文档描述2.1 创建方式
一个就是直接调用open方法public static Selector open() throws IOException { return SelectorProvider.provider().openSelector(); }
或者调用选用某个SelectorProvider的openSelector
public abstract AbstractSelector openSelector()
2.2 SelectionKey
一个Selector有3种SelectionKey集合一种就是全部注册的SelectionKey集合,即keys()方法返回的结果
一种就是活跃的SelectionKey集合,即selectedKeys()方法返回的结果
第三种就是已取消的SelectionKey集合,这些已被取消但是还未从Selector取消注册
再确认下下面的几个问题:
什么叫注册
即将一个channel感兴趣的事件注册到Selector上,即如下方法
SelectionKey register(AbstractSelectableChannel ch, int ops, Object att)
对于select、poll的Selector实现:仅仅是保存上述AbstractSelectableChannel感兴趣的ops到指定地方
对于epoll的Selector实现:则是执行系统调用epoll_ctl方法,操作参数是EPOLL_CTL_ADD
什么叫取消
就是调用SelectionKey的cancel方法,该方法的实现是,将该SelectionKey放入cancelledKeys而已,没有做其他操作
什么叫取消注册
取消注册,就是从Selector从释放出来不再关注某个事件。通常在我们的select过程中就会遍历上述cancelledKeys,依次执行取消注册的行为。不同的Selector有不同的行为,如epoll则是执行系统调用epoll_ctl方法,操作参数是EPOLL_CTL_DEL。
2.3 三种select方式
分别如下:int select():表示一直阻塞到有事件为止 int select(long timeout):最多阻塞timeout时间 int selectNow():不阻塞,检查结果后立即返回
2.4 并发性
Selector不是线程安全的,不过大部分情况都是一个线程拥有一个Selector,所以不需要它线程安全。2.5 使用案例
以ZooKeeper为例,代码简述如下final Selector selector = Selector.open(); public void run() { while (!ss.socket().isClosed()) { try { selector.select(1000); Set<SelectionKey> selected = selector.selectedKeys(); for (SelectionKey k : selected) { if ((k.readyOps() & SelectionKey.OP_ACCEPT) != 0) { //执行accept连接的事件 SocketChannel sc = ((ServerSocketChannel) k .channel()).accept(); sc.configureBlocking(false); SelectionKey sk = sc.register(selector, SelectionKey.OP_READ); NIOServerCnxn cnxn = createConnection(sc, sk); sk.attach(cnxn); addCnxn(cnxn); } else if ((k.readyOps() & (SelectionKey.OP_READ | SelectionKey.OP_WRITE)) != 0) { //执行IO读写事件 NIOServerCnxn c = (NIOServerCnxn) k.attachment(); c.doIO(k); } else { //未知 } } selected.clear(); } catch (RuntimeException e) { LOG.warn("Ignoring unexpected runtime exception", e); } catch (Exception e) { LOG.warn("Ignoring exception", e); } } closeAll(); LOG.info("NIOServerCnxn factory exited run method"); }
while循环里面不断调用selector.select(1000)方法,然后通过selector.selectedKeys()来获取到有事件的SelectionKey集合,即上述提到的活跃的SelectionKey集合。然后遍历该集合,执行对应的事件。
3 不同实现类
目前Selector目前有如下实现针对linux平台的实现:
PollSelectorImpl:基于poll来实现
EPollSelectorImpl:基于epoll来实现
针对windows平台的实现:
WindowsSelectorImpl
而Netty的NioEventLoop则是使用上述linux平台的实现PollSelectorImpl。Netty自己提供了另外一种epoll实现,没有直接采用上述jdk自带的EPollSelectorImpl。
4 后续
接下来就要开始重点说说jdk的poll是怎么实现的,即PollSelectorImpl的内容相关文章推荐
- 【JDK集合框架源码分析】-集合框架概述
- jdk的Selector源码分析(二)poll方式实现
- jdk源码分析 ——Selector深入分析
- JDK 源码分析 Day 1
- jquery Selector 源码分析
- Velocity源码分析(一)――概述
- JDK源码分析:java.lang.Boolean
- JDK源码分析之java.util.ArrayList
- JDK源码分析:java.lang.String
- JDK源码分析——Java.util.Vector的浅析
- jdk源码分析 – Thread线程类源码分析
- 安卓图表引擎AChartEngine(二) - 示例源码概述和分析
- JDK源码分析:java.lang.Boolean
- JDK源码分析——Java.util.Vector的浅析
- 安卓图表引擎AChartEngine(二) - 示例源码概述和分析
- BitSet数据结构以及jdk中实现源码分析
- Mathopd源码分析——概述
- CSS selector (jquery的源码分析,修改)
- JDK源码分析——研究 Hash 存储机制
- Glusterfs之rpc模块源码分析(上)之RPC概述