前段時間閱讀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:
寫道
Windows XP
5.1
sun.nio.ch.WindowsSelectorProvider@1fb8ee3
ubuntu 11.04:
寫道
Linux
2.6.38-8-generic
sun.nio.ch.EPollSelectorProvider@160c21a
JDK對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