2015-11-13 17 views
6

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?

risposta

5

Se viene rilevato il kernel linux> = 2.6, il java.nio.channels.spi.SelectorProvider utilizzerà epoll.

Ecco un pezzo del DefaultSelectorProvider.javasource (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).

+0

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? –

+0

"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

+0

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 :) –