文档章节

jdk的Selector源码分析(一)Selector概述

乒乓狂魔
 乒乓狂魔
发布于 2016/08/16 18:11
字数 799
阅读 323
收藏 0

1系列内容

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目前有如下实现

Selector实现类

针对linux平台的实现:

  • PollSelectorImpl:基于poll来实现
  • EPollSelectorImpl:基于epoll来实现

针对windows平台的实现:

  • WindowsSelectorImpl

而Netty的NioEventLoop则是使用上述linux平台的实现PollSelectorImpl。Netty自己提供了另外一种epoll实现,没有直接采用上述jdk自带的EPollSelectorImpl。

4 后续

接下来就要开始重点说说jdk的poll是怎么实现的,即PollSelectorImpl的内容

© 著作权归作者所有

共有 人打赏支持
乒乓狂魔
粉丝 1011
博文 105
码字总数 271356
作品 0
长宁
程序员
私信 提问
NIO 之 Selector实现原理

相关文章 NIO 之 ByteBuffer实现原理 NIO 之 Channel实现原理 BIO、NIO、AIO 内部原理分析 概述 Selector允许单线程处理多个 Channel。如果你的应用打开了多个连接(通道),但每个连接的流量...

轨迹_
06/22
0
0
netty源码分析之揭开reactor线程的面纱(二)

如果你对netty的reactor线程不了解,建议先看下上一篇文章netty源码分析之揭开reactor线程的面纱(一),这里再把reactor中的三个步骤的图贴一下 我们已经了解到netty reactor线程的第一步是...

闪电侠_
08/02
0
0
Netty源码分析(二)EventLoopGroup分析

准备将Netty的源码过一下,一来对自己是个总结消化的过程,二来希望对那些打算看Netty源码的人(已经熟悉Netty的Reactor模型)能有一些帮助。目前所看Netty版本是4.1.3.Final。 1 目录 - Ne...

乒乓狂魔
2016/09/06
421
0
netty源码分析之揭开reactor线程的面纱(一)

netty最核心的就是reactor线程,对应项目中使用广泛的NioEventLoop,那么NioEventLoop里面到底在干些什么事?netty是如何保证事件循环的高效轮询和任务的及时执行?又是如何来优雅地fix掉jdk...

闪电侠_
07/31
0
0
java bio,nio,aio及源码

版权声明:本文为博主原创文章,未经博主允许不得转载。 目录(?)[+] NIO 简介 随着JavaIO类库的不断发展和改进,基于Java的网络编程会变得越来越简单。随着异步IO功能的增强,基于JavaNIO开发...

onedotdot
2017/10/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

EOS docker开发环境

使用eos docker镜像是部署本地EOS开发环境的最轻松愉快的方法。使用官方提供的eos docker镜像,你可以快速建立一个eos开发环境,可以迅速启动开发节点和钱包服务器、创建账户、编写智能合约....

汇智网教程
今天
3
0
《唐史原来超有趣》的读后感优秀范文3700字

《唐史原来超有趣》的读后感优秀范文3700字: 作者:花若离。我今天分享的内容《唐史原来超有趣》这本书的读后感,我将这本书看了一遍之后就束之高阁了,不过里面的内容一直在在脑海中回放,...

原创小博客
今天
6
0
IC-CAD Methodology知识图谱

CAD (Computer Aided Design),计算机辅助设计,指利用计算机及其图形设备帮助设计人员进行设计工作,这个定义同样可以用来近似描述IC公司CAD工程师这个岗位的工作。 早期IC公司的CAD岗位最初...

李艳青1987
今天
7
0
CompletableFuture get方法一直阻塞或抛出TimeoutException

问题描述 最近刚刚上线的服务突然抛出大量的TimeoutException,查询后发现是使用了CompletableFuture,并且在执行future.get(5, TimeUnit.SECONDS);时抛出了TimeoutException异常,导致接口响...

xiaolyuh
今天
5
0
dubbo 搭建与使用

官网:http://dubbo.apache.org/en-us/ 一,安装监控中心(可以不安装) admin管理控制台,monitor监控中心 下载 bubbo ops 这个是新版的,需要node.js环境,我没有就用老版的了...

小兵胖胖
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部