wdeo0 2012-12-26
前段时间阅读mina源码时,理解Selector实例化机制细节有点疑惑疑惑,主要是SelectorProvider的细节实现方面。
通常创建一个Selector,通过静态open方法创建一个实例。代码如下:
Selector selector = Selector.open();
观察JDK源码发现Select的创建通过SelectorProvider辅助类来完成:
public static Selector open() throws IOException { return SelectorProvider.provider().openSelector(); }
进一步观察SelectorProvider类provider方法源码,引用到类sun.nio.ch.DefaultSelectorProvider,开始的时候由于在JDK API
中没找到该类,源码里面也没找到,比较疑惑如何创建的。今天在rt.jar找到了该类,并找到其对源码。
/** * Returns the default SelectorProvider. */ public static SelectorProvider create() { PrivilegedAction pa = new GetPropertyAction("os.name"); String osname = (String) AccessController.doPrivileged(pa); if ("SunOS".equals(osname)) {//1、如果SunOS return new sun.nio.ch.DevPollSelectorProvider(); } //2、Linux 内核>=2.6 // 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(); }
其create方法根据不同的操作系统构建不同的SelectorProvider,主要分为unix、linux,other,linux针对内核2.6以上
通过epoll。获取系统环境中的os.name、os.version观察下不同平台的细节。
System.out.println(System.getProperty("os.name")); System.out.println(System.getProperty("os.version")); System.out.println(java.nio.channels.spi.SelectorProvider.provider());
通过在不同的操作系统上执行如下代码即可区分:
win XP sp3:
5.1
sun.nio.ch.WindowsSelectorProvider@1fb8ee3ubuntu 11.04:
2.6.38-8-generic
sun.nio.ch.EPollSelectorProvider@160c21aJDK对linux内核2.6以上版本默认采用epoll,Linux下性能得到一定幅度提升。
参考:
DefaultSelectorProvider源码:http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Platform/solaris/sun/nio/ch/DefaultSelectorProvider.java.htm