http://blog.csdn.net/hsuxu/article/details/9876983

之前强调这么多关于linux内核的poll及epoll,无非是想让大家先有个认识:

Java NIO中的选择器依赖操作系统内核的这些系统调用,我们这里只讲解与linux内核相关的NIO实现,当然,windows或其他操作系统实现大体上是类似的,相信大家也可以触类旁通。

那么,本文从这里将从简到难,一步一步为大家讲解选择器的点点滴滴吧。

选择器的宏观理解
“有这么一种检查员,她工作在养鸡场,每天的工作就是不停的查看特定的鸡舍,如果有鸡生蛋了,或者需要喂食,或者有鸡生病了,就把相应信息记录下来,这样一来,鸡舍负责人想知道鸡舍的情况,只需要到检查员那里查询即可,当然,鸡舍负责人得事先告知检查员去查询哪些鸡舍。“

以上这段话即为选择器所做工作的一个比喻,实际上选择器为通道服务,通道事先告诉选择器:“我对某些事件感兴趣,如可读、可写等“,选择器在接受了一个或多个通道的委托后,开始选择工作,它的选择工作就完全交给操作系统,linux下即为poll或epoll。

选择器的创建
当调用Selector.open()时,选择器通过专门的工厂SelectorProvider来创建Selector的实现,SelectorProvider屏蔽了不同操作系统及版本创建实现的差异性。具体实现代码如下:

java.nio.channels.Selector

public static Selector open() throws IOException {
    return SelectorProvider.provider().openSelector();
}
因为SelectorProvider本身为一个抽象类,通过调用provider()提供对应的Provider实现,如PollSelectorProvider、EPollSelectorProvider

java.nio.channels.spi.SelectorProvider

public static SelectorProvider provider() {
synchronized (lock) {
    if (provider != null)
    return provider;
    return (SelectorProvider)AccessController
    .doPrivileged(new PrivilegedAction() {
        public Object run() {
            if (loadProviderFromProperty())
            return provider;
            if (loadProviderAsService())
            return provider;
            provider = sun.nio.ch.DefaultSelectorProvider.create();
            return provider;
        }
        });
}
}
默认的Provider实现即为DefaultSelectorProvider,通过调用create(),得到具体的SelectorProvider

sun.nio.ch.DefaultSelectorProvider

public static SelectorProvider create() {
PrivilegedAction pa = new GetPropertyAction("os.name");
String osname = (String) AccessController.doPrivileged(pa);
    if ("SunOS".equals(osname)) {
        return new sun.nio.ch.DevPollSelectorProvider();
    }
 
    // use EPollSelectorProvider for Linux kernels >= 2.6
    if ("Linux".equals(osname)) {
        pa = new GetPropertyAction("os.version");
        String osversion = (String) AccessController.doPrivileged(pa);
        String[] vers = osversion.split("\\.", 0);
        if (vers.length >= 2) {
            try {
                int major = Integer.parseInt(vers[0]);
                int minor = Integer.parseInt(vers[1]);
                if (major > 2 || (major == 2 && minor >= 6)) {
                    return new sun.nio.ch.EPollSelectorProvider();
                }
            } catch (NumberFormatException x) {
                // format not recognized
            }
        }
    }
 
    return new sun.nio.ch.PollSelectorProvider();
}
这是linux操作系统下的DefaultSelectorProvider的实现,可以看到,如果内核版本>=2.6则,具体的SelectorProvider为EPollSelectorProvider,否则为默认的PollSelectorProvider

结合上文,可以猜测一下EPollSelectorProvider提供的Selector肯定是与内核epoll有关的,PollSelectorProvider提供的
Selector肯定是与poll有关的。的确如此:

sun.nio.ch.EPollSelectorProvider

public AbstractSelector openSelector() throws IOException {
    return new EPollSelectorImpl(this);
}
sun.nio.ch.PollSelectorProvider

public AbstractSelector openSelector() throws IOException {
    return new PollSelectorImpl(this);
}

Java NIO 选择器(Selector)的内部实现(poll epoll)的更多相关文章

  1. Java NIO 选择器(Selector)的内部实现(poll epoll)(转)

    转自:http://blog.csdn.net/hsuxu/article/details/9876983 之前强调这么多关于linux内核的poll及epoll,无非是想让大家先有个认识: Java ...

  2. Java NIO之Selector(选择器)

    历史回顾: Java NIO 概览 Java NIO 之 Buffer(缓冲区) Java NIO 之 Channel(通道) 其他高赞文章: 面试中关于Redis的问题看这篇就够了 一文轻松搞懂re ...

  3. Java NIO类库Selector机制解析(上)

    一.  前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...

  4. Java NIO类库Selector机制解析--转

    一.  前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...

  5. Java NIO类库Selector机制解析(下)

    五.  迷惑不解 : 为什么要自己消耗资源? 令人不解的是为什么我们的Java的New I/O要设计成这个样子?如果说老的I/O不能多路复用,如下图所示,要开N多的线程去挨个侦听每一个Channel ...

  6. NIO 选择器 Selector

    选择器提供选择执行已经就绪的任务的能力,这使得多元 I/O 成为可能.就像在第一章中描述的那样,就绪选择和多元执行使得单线程能够有效率地同时管理多个 I/O 通道(Channels).C/C++代码的 ...

  7. Java NIO之Selector

    选择器是JavaNIO重磅推出的一个概念:在旧有的系统中为了跟踪多端口消息,需要为每一个端口配备一个线程做监听:但是有了selector就不需要了,一个Selector可以管理一众渠道(channel ...

  8. JAVA NIO 选择器

    为什么要使用选择器 通道处于就绪状态后,就可以在缓冲区之间传送数据.可以采用非阻塞模式来检查通道是否就绪,但非阻塞模式还会做别的任务,当有多个通道同时存在时,很难将检查通道是否就绪与其他任务剥离开来, ...

  9. JAVA NIO 之 Selector 组件

    NIO 重要功能就是实现多路复用.Selector是SelectableChannel对象的多路复用器.一些基础知识: 选择器(Selector):选择器类管理着一个被注册的通道集合的信息和它们的就绪 ...

随机推荐

  1. app图片规格

    我们定义的app图片规格 app图标需要分iphone和android两套 iphone: 名称 Iphone4 Iphone5 手机尺寸 960*640(高*宽) 1136*640 (高*宽) 电池 ...

  2. [转]"由于这台计算机没有远程桌面客户端访问许可证,远程会话被中断"的解决方案

    先使用如下命令登录到服务器: mstsc /v:{服务器IP} /admin 然后再使用下列方法之一即可. 方法一: 1.单击“开始→运行”,输入“gpedit.msc”打开组策略编辑器窗口,依次定位 ...

  3. jquery 列求和

    列求和 var m = 0; $('#tb tr').each(function () { //td:eq(3)从0开始计数 $(this).find('td:eq(3)').each(functio ...

  4. 华为 2015 机试 输出:数字后面的连续出现的(2个或多个)相同字符(数字或者字符),删去一个,非数字后面的不要删除,例如,对应输出为:33aabb55pin。

    package 华为机试; //C++ 输入:由数字和字母组成的字符串,例如:333aaabb55ppin //输出:数字后面的连续出现的(2个或多个)相同字符(数字或者字符),删去一个,非数字后面的 ...

  5. POJ 1655 Balancing Act (求树的重心)

    求树的重心,直接当模板吧.先看POJ题目就知道重心什么意思了... 重心:删除该节点后最大连通块的节点数目最小 #include<cstdio> #include<cstring&g ...

  6. PHP邮箱验证是否有效

    今天一开电脑发现有人在我的主页给我乱留言,所以加了一个邮箱验证. 网上发现一个很巧妙的算法,分享一下: function checkmail($email){ $exp = "^[a-z'0 ...

  7. json里的日期字符串 怎么 转换成 javascript 的 Date 对象?

    “/Date(1232035200000)/” 怎么转换成  javascript 的 Date 对象 做法:new Date(+/\d+/.exec(value)[1]); value就是json字 ...

  8. 代码修改mysql字符

    为了不再显示的时候乱码,要修改数据库默认编码.以下以GBK编码页面为例进行说明: 1.修改MYSQL的配置文件:my.ini里面修改default-character-set=gbk2.代码运行时修改 ...

  9. A Tour of Go For continued

    As in C or Java, you can leave the pre and post statements empty. package main import "fmt" ...

  10. STM32F407 ADC DMA 采样实验

    转载:http://home.eeworld.com.cn/my/space-uid-361439-blogid-239703.html STM32F407ADC采样实验 热度 1已有 5472 次阅 ...