转自: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 NI ...

  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. 创建第一个maven项目的那些坑

    1.记事本方式: class所在的目录结构: class的代码书写: package com.imooc.maven01.mode1; public class HelloWorld { public ...

  2. 【bzoj3924&&luogu3345】幻想乡战略游戏

    这题可以用线段树做,不过正解恐怕是动态点分治?(点分树) 简单介绍下动态点分治的概念:在点分治的过程中,一般我们面对的问题都是静态的.如果涉及到修改这类的操作,我们就希望找到我们是如何处理到当前的修改 ...

  3. C++ Primer 阅读笔记:迭代器和容器 小结

    原创 by zoe.zhang  0.写在前面的话 我是在2011年学的C++,但是那一年恰好是C++11新标准的一年,但是大学上学的C++还是基于C++98的风格的,使用的编译器也是VC6.0,啊, ...

  4. WPF拖放功能实现

    写在前面:本文为即兴而作,因此难免有疏漏和词不达意的地方.在这里,非常期望您提供评论,分享您的想法和建议. 这是一篇介绍如何在WPF中实现拖放功能的短文. 首先要读者清楚的一件事情是:拖放主要分为拖放 ...

  5. 转载 Ofbiz 入门教程

    1.Ofbiz 介绍: Ofbiz(http://www.ofbiz.org) 是 Open Source 的商务软件系统,充分利用了各优秀的的Open Source 项目,像 Tomcat, Ant ...

  6. Android仿QQ登录下拉历史列表

    demo中包含了Sqlite数据库增删改查,对存储的账号进行按照最新的时间排序,限制了最多存储5条数据. 效果图: 1.首先创建MyHelper建表: public class MyHelper ex ...

  7. python 根据文件创建时间排序

    #coding:utf8 import os,time directory = "d:/scrapy tutorial/" t = [] d = {} for filename i ...

  8. android9.0请求异常

    抛出异常:CLEARTEXT communication to not permitted by network security policy android 9开始默认不能使用http 1.在re ...

  9. STL优先队列——踩坑日记

    priority_queue 可以定义STL中的优先队列,但是优先队列在应用于自己定义的类型时需要重载<运算符,或者通过仿函数来定义比较方法,在定义比较方法的过程中,比较大的坑是STL中对于参数 ...

  10. 训练指南 UVALive - 3713 (2-SAT)

    layout: post title: 训练指南 UVALive - 3713 (2-SAT) author: "luowentaoaa" catalog: true mathja ...