我正在研究不同语言的网络IO API的体系结构,并询问了如何在Java下实现Java中的Async IO API。 “旧”流IO API(1.4之前的版本)提供了同步阻塞读/写功能。 JDK 1.4 NIO API使用epoll / select来测试IO就绪(通过SelectableChannel和Selector等向用户公开)。这可能是Windows和* nix的情况。这是反应堆模式。现在,JDK7引入了NIO.2 API,其中包括提供异步API(主动模式),并使用内部(可配置)线程池在后台执行IO,并在完成后回调用户代码。它可能在Windows上使用IOCP,但我想知道: 1.它在Linux上使用了什么,这是我感兴趣的主要平台。它是使用epoll和朋友,还是使用线程池来阻止IO? 2. NIO.2中的实际IO(无论平台)是由Java线程池中的用户线程完成的,还是由内核线程完成的,而Java线程池线程只负责复制字节缓冲区并回调用户代码?
答案 0 :(得分:7)
如果检测到linux内核> = 2.6,那么java.nio.channels.spi.SelectorProvider
将使用epoll。
以下是DefaultSelectorProvider.java
source(来自Java 7)的一部分:
public static SelectorProvider create() {
String osname = AccessController.doPrivileged(
new GetPropertyAction("os.name"));
if ("SunOS".equals(osname)) {
return new sun.nio.ch.DevPollSelectorProvider();
}
// use EPollSelectorProvider for Linux kernels >= 2.6
if ("Linux".equals(osname)) {
String osversion = AccessController.doPrivileged(
new GetPropertyAction("os.version"));
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();
}
NIO 2和"原创"一个(让他们称之为NIO 1)必须使用低级事件通知机制或Linux AIO API(这是相对较新的),因为你永远不知道应用程序运行的机器上的内核是什么。我不会惊讶地发现NIO 2实际上使用的是Linux AIO或POSIX AIO(它们完全不同)。