2009-02-26 22 views
56

¿Qué opciones para async io (socket-based) hay en java otra que java.nio? También java.nio utiliza hilos en el backround (como creo que async-socket-library de .NET, tal vez ha sido cambiado) o es "asincrónico" verdadero usando una llamada de selección apropiada?IO asincrónico en Java?

+6

Donde la secuencia subyacente lo admite,.NET usa puertos de terminación IO y un hilo ThreadPool para ejecutar devoluciones de llamada. –

+0

Jon, ¿cuándo podría la transmisión subyacente NO soportarlo? –

+0

¿Alguna razón específica acerca de por qué no usar java.nio? En realidad, estoy tratando de implementar algunas E/S asíncronas en mi proyecto en el trabajo y no he usado ninguno de estos antes. Por lo tanto, quería saber. Gracias. – Bhushan

Respuesta

44

El paquete NIO de Java (a partir de Java6), admite E/S sin bloqueo solamente, a través de Selector s. Se espera que Java7 se envíe con NIO.2, que incluye soporte de E/S asíncronas. Hoy, tu mejor opción es hacer uso de un marco. ARMistice mencionó a Mina. Aquí hay algunos otros.

  1. Grizzly. Este es el núcleo de E/S para el servidor GlassFish de Sun. Grizzly proporciona una facilidad para realizar lecturas/escrituras asincrónicas (a través de un modelo de cola). Es compatible con TCP y UDP por igual. He usado Grizzly en un par de proyectos. Hay cosas que me gustan y las que no me gustan del marco, pero detallar esto es realmente otro tema. Diré que es bastante fácil poner en marcha algo y Grizzly hace mucho trabajo pesado por ti.
  2. Netty. Este proyecto proviene de uno de los autores originales del proyecto Mina. No he usado este, así que no sé sobre su soporte para E/S asincrónicas. Deberías echar un vistazo.

Ahora, con respecto a su pregunta sobre los hilos, los selectores de NIO no usan hilos para E/S sin bloqueo. En JDK6 usan select() en Windows y la instalación epoll en kernels Linux más nuevos. Para E/S asíncrona, los detalles de subprocesamiento dependen del marco.

+1

El NIO de Java también admite el bloqueo de IO. ;) –

+1

Netty es asíncrono y controlado por eventos como MINA. Consulte los testimonios y los informes de rendimiento escritos por usuarios reales en la página de inicio. :) – trustin

+0

Parece que Java 7 efectivamente lanzó con asincronización de E/S: http://openjdk.java.net/projects/nio/presentations/TS-5686.pdf –

12

java.nio es solo un paquete, una colección de clases "tontas", por sí solo no utiliza ningún uso de subprocesos. Cuando se usa correctamente, como en el Reactor design pattern, puede lograr E/S asíncronas correctas, totalmente escalables.

+0

Tu respuesta me parece legítima, pero ¿puedes explicar más? Un poco más de explicaciones, por favor. –

6

Si está interesado en usarlo para Network Stuff. Una muy buena opción es:

http://mina.apache.org/

echar un vistazo aquí es fácil de usar y muy potente.

15

Otra sugerencia en lo que respecta a libs sería Naga (http://naga.googlecode.com). Es un poco menos como un marco y más como una biblioteca. Trata de parecerse más a las tomas de java ordinarias, si esa es tu taza de té. Es minimalista en comparación con Grizzly, Mina y Netty.

+0

Naga en realidad parece una muy buena envoltura alrededor de las cosas asincrónicas. –

+1

Si solo quiere hacer una E/S de socket asíncrona sin un marco que se interponga en su camino, Naga es lo que quiere. – poindexter

+1

¿Los naga funcionan bien con Dalvik/Android? –

2

A la pregunta original, la implementación solo consume un subproceso por operación de E/S en un caso, AsynchronousFileChannel en sistemas Unix/Linux.

16

JAVA 7 llegó la respuesta tan nueva es NIO.2 con clase Future. Ejemplo:

En el lado del servidor:

final AsynchronousServerSocketChannel serverSocket= 
    AsynchronousServerSocketChannel.open().bind(new InetSocketAddress("127.0.0.1", 2587)); // Listening on port 2587 for client connection 
Future<AsynchronousSocketChannel> future= serverSocket.accept(); 
final AsynchronousSocketChannel clientSocket= future.get(); // now it's blocking, useful: future.isDone() and .isCancelled() 

//Do whatever you want .. 
InputStream stream = Channels.newInputStream(clientSocket) (...) 

En el lado del cliente:

AsynchronousSocketChannel clientChannel = AsynchronousSocketChannel.open(); 
Future connected = localSocket.connect(ourServerSocketAddress); 
// later: if(future.isDone()) 
connected.get(); 

//Send something 
OutputStream os = Channels.newOutputStream(clientChannel); 
os.write (...) 

Actualización: Si puede utilizar modelo de actor a continuación AKKA TCP IO sería aún mejor.

+3

El futuro no es verdadero asincrónico. Está basado en subprocesos/semáforos: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html – Josmar

+9

¿Qué es "asincrónico verdadero"? - El hecho de que se implemente utilizando hilos no significa que no sea asincrónico ... – DejanLekic