java epoll nio_Java NIO 选择器(Selector)的内部实现(poll epoll)

之前强调这么多关于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); }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值