Java NIO 选择器(Selector)的内部实现(poll epoll)
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)的更多相关文章
- Java NIO 选择器(Selector)的内部实现(poll epoll)(转)
转自:http://blog.csdn.net/hsuxu/article/details/9876983 之前强调这么多关于linux内核的poll及epoll,无非是想让大家先有个认识: Java ...
- Java NIO之Selector(选择器)
历史回顾: Java NIO 概览 Java NIO 之 Buffer(缓冲区) Java NIO 之 Channel(通道) 其他高赞文章: 面试中关于Redis的问题看这篇就够了 一文轻松搞懂re ...
- Java NIO类库Selector机制解析(上)
一. 前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...
- Java NIO类库Selector机制解析--转
一. 前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...
- Java NIO类库Selector机制解析(下)
五. 迷惑不解 : 为什么要自己消耗资源? 令人不解的是为什么我们的Java的New I/O要设计成这个样子?如果说老的I/O不能多路复用,如下图所示,要开N多的线程去挨个侦听每一个Channel ...
- NIO 选择器 Selector
选择器提供选择执行已经就绪的任务的能力,这使得多元 I/O 成为可能.就像在第一章中描述的那样,就绪选择和多元执行使得单线程能够有效率地同时管理多个 I/O 通道(Channels).C/C++代码的 ...
- Java NIO之Selector
选择器是JavaNIO重磅推出的一个概念:在旧有的系统中为了跟踪多端口消息,需要为每一个端口配备一个线程做监听:但是有了selector就不需要了,一个Selector可以管理一众渠道(channel ...
- JAVA NIO 选择器
为什么要使用选择器 通道处于就绪状态后,就可以在缓冲区之间传送数据.可以采用非阻塞模式来检查通道是否就绪,但非阻塞模式还会做别的任务,当有多个通道同时存在时,很难将检查通道是否就绪与其他任务剥离开来, ...
- JAVA NIO 之 Selector 组件
NIO 重要功能就是实现多路复用.Selector是SelectableChannel对象的多路复用器.一些基础知识: 选择器(Selector):选择器类管理着一个被注册的通道集合的信息和它们的就绪 ...
随机推荐
- git 版本历史
版本:git rev-parse --git-dir显示Git版本库的位置 --show-cdup显示当前工作区目录的深度 --parseopt解析命令行参数 $ git rev-parse - ...
- POJ1050:To the max
poj1050:http://poj.org/problem?id=1050 * maximum-subarray 问题的升级版本~ 本题同样是采用DP思想来做,同时有个小技巧处理:就是把二维数组看做 ...
- 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 ...
- 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 ...
- hadoop-2.6.0.tar.gz + spark-1.5.2-bin-hadoop2.6.tgz 的集群搭建(3节点和5节点皆适用)
本人呕心沥血所写,经过好一段时间反复锤炼和整理修改.感谢所参考的博友们!同时,欢迎前来查阅赏脸的博友们收藏和转载,附上本人的链接.http://www.cnblogs.com/zlslch/p/584 ...
- Altium Designer 多通道设计
转chenzelin2009的csdn博客:http://blog.csdn.net/chenzelin2009/article/details/5751251# Altium Designer的多图 ...
- 在触屏设备中拖动 overflow 元素
在 Android 和 iOS 等触屏设备中,如果网页中某元素设置 overflow: auto 或者 overflow:scroll,那么问题就来了.在 Android 3.0 之前以及 iPhon ...
- Java 动态生成 复杂 .doc文件
阅读目录 1.word 里面调整好排版,包括你想生成的动态部分,还有一些不用生成的规则性的文字 2. 将 word 文档保存为 xml 3.用 Firstobject free XML edito 打 ...
- python学习(3)
Python学习(3)切片(Slice):根据索引范围取出字符串里面的内容,比如: l=range(100) l[:8] [0, 1, 2, 3, 4, 5, 6, 7] ...
- java和c#md5加密不同
java的mad5加密后为32位字符串,c#直接加密后可能不是32位,位数也不确定. 普通的写法 public static string Md5(string sourcein) { var md5 ...