Sto studiando l'architettura delle API IO di rete in lingue diverse e ho una query su come le API Async IO in Java sono implementate sotto. Le API IO "stream" precedenti (pre 1.4) offrivano funzionalità di lettura/scrittura blocco sincrono. Le API NIO JDK 1.4 utilizzano epoll/select per testare la prontezza dell'IO (esposte agli utenti tramite SelectableChannel e Selector, ecc.). Questo è presumibilmente il caso sia su Windows che su * nix. Questo è il modello del reattore. Ora, JDK7 ha introdotto l'API NIO.2 che, tra le altre cose, offre un'API asincrona (pattern del proact) e utilizza pool di thread interni (configurabili) per eseguire IO in background e callback al codice utente al termine. Presumibilmente utilizza IOCP su Windows, ma mi chiedevo: 1. che cosa usa su Linux, che è la mia principale piattaforma di interesse. Usa epoll e amici o usa un threadpool per bloccare l'IO? 2. L'I/O effettivo in NIO.2 (indipendentemente dalla piattaforma) eseguito dai thread utente nel threadpool Java o è eseguito dai thread del kernel e i thread del threadpool Java sono responsabili della copia dei bytebuffer e della richiamata dell'utente codice?JDK7 NIO.2 usa Epoll ecc. Su Linux?
6
A
risposta
5
Se viene rilevato il kernel linux> = 2.6, il java.nio.channels.spi.SelectorProvider
utilizzerà epoll.
Ecco un pezzo del DefaultSelectorProvider.java
source (da 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();
}
Sia NIO 2 e il "originale" uno (chiamiamolo NIO 1) hanno di utilizzare la notifica degli eventi di basso livello meccanismi o API AIO Linux (che è relativamente nuova) perché non si sa mai quale sarà il kernel sulla macchina in esecuzione. Non sarei sorpreso di vedere che NIO 2 utilizza effettivamente Linux AIO o POSIX AIO (sono piuttosto diversi).
NIO.2 utilizza persino SelectorProvider? Quello di cui non sono troppo sicuro è se l'implementazione di Async in NIO.2 sia simile al modo NIO di fare le cose usando i controlli di readiness tramite Epoll, ecc. Oppure simula async usando un pool di thread che blocca io? –
"simula async" ?? Non esiste una "simulazione" - ogni framework asincrono utilizza il pre-elaborazione (thread) o il multitasking cooperativo (fibre, coroutine, fili verdi) per implementare la gestione asincrona. – DejanLekic
Per quanto ne so, AsynchronousFileChannel blocca il file sincrono letto su un pool, quindi non è vero asincrono ma simulazione. D'altra parte seleziona per socket che è vero asincrono :) –