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. git 版本历史

    版本:git rev-parse --git-dir显示Git版本库的位置   --show-cdup显示当前工作区目录的深度  --parseopt解析命令行参数 $ git rev-parse - ...

  2. POJ1050:To the max

    poj1050:http://poj.org/problem?id=1050 * maximum-subarray 问题的升级版本~ 本题同样是采用DP思想来做,同时有个小技巧处理:就是把二维数组看做 ...

  3. How to select a OptionSet on ms sqlserver database for Microsoft Dynamics CRM

    OptionSet: Select * from StringMap Global OptionSet: select  os.Name, l.Label from AttributePicklist ...

  4. HDU5407.CRB and Candies(数论)

    官方题解: The problem is just to calculate g(N) = LCM(C(N,0),C(N,1),...,C(N,N)) Introducing function f(n ...

  5. hadoop-2.6.0.tar.gz + spark-1.5.2-bin-hadoop2.6.tgz 的集群搭建(3节点和5节点皆适用)

    本人呕心沥血所写,经过好一段时间反复锤炼和整理修改.感谢所参考的博友们!同时,欢迎前来查阅赏脸的博友们收藏和转载,附上本人的链接.http://www.cnblogs.com/zlslch/p/584 ...

  6. Altium Designer 多通道设计

    转chenzelin2009的csdn博客:http://blog.csdn.net/chenzelin2009/article/details/5751251# Altium Designer的多图 ...

  7. 在触屏设备中拖动 overflow 元素

    在 Android 和 iOS 等触屏设备中,如果网页中某元素设置 overflow: auto 或者 overflow:scroll,那么问题就来了.在 Android 3.0 之前以及 iPhon ...

  8. Java 动态生成 复杂 .doc文件

    阅读目录 1.word 里面调整好排版,包括你想生成的动态部分,还有一些不用生成的规则性的文字 2. 将 word 文档保存为 xml 3.用 Firstobject free XML edito 打 ...

  9. python学习(3)

    Python学习(3)切片(Slice):根据索引范围取出字符串里面的内容,比如: l=range(100)   l[:8] [0, 1, 2, 3, 4, 5, 6, 7]              ...

  10. java和c#md5加密不同

    java的mad5加密后为32位字符串,c#直接加密后可能不是32位,位数也不确定. 普通的写法 public static string Md5(string sourcein) { var md5 ...