JDK7 NIO.2在Linux上使用Epoll等吗?

时间:2015-11-13 12:40:20

标签: java asynchronous nio

我正在研究不同语言的网络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线程池线程只负责复制字节缓冲区并回调用户代码?

1 个答案:

答案 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(它们完全不同)。