I am studying the architecture of networking IO APIs in different languages and had a query on how the Async IO APIs in Java are implemented underneath. The "old" stream IO APIs (pre 1.4) offered synchronous blocking read/write functionality. JDK 1.4 NIO APIs use epoll/select to test IO readiness (exposed to users via SelectableChannel and Selector, etc.). This is presumably the case on both Windows and *nix. This is the reactor pattern. Now, JDK7 introduced the NIO.2 API which, among other things, offers an asynchronous API (proactor pattern) , and uses internal (configurable) thread pools to do IO in the background, and callback to user code when complete. It presumably uses IOCP on Windows, but I was wondering: 1. what does it use on Linux, which is my primary platform of interest. Does it use epoll and friends, or does it use a threadpool to do blocking IO? 2. Is the actual IO in NIO.2 (irrespective of platform) done by user threads in the Java threadpool, or is it done by kernel threads, and the Java threadpool threads are responsible for just copying the bytebuffers and calling back to user code?
If linux kernel >= 2.6 is detected, then the java.nio.channels.spi.SelectorProvider
will use epoll.
Here is a piece of the DefaultSelectorProvider.java
source (from 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();
}
Both NIO 2 and the "original" one (let's call it NIO 1) have to use the low-level event notification mechanisms or Linux AIO API (which is relatively new) because you never know what will be the kernel on machine your application runs. I would not be surprised to see that NIO 2 actually uses Linux AIO or maybe POSIX AIO (they are quite different).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With