2012-05-21 12 views
7

¿Hay alguna diferencia entre un canal Go y un Java BlockingQueue? Ambas son colas con bloqueo similar y semántica de modelo de memoria. Opcionalmente, ambos pueden tener un conjunto de capacidades.Go channel vs Java BlockingQueue

Respuesta

12

Diría que la mayor diferencia es que los canales Go tienen soporte para la instrucción select, que le permite realizar exactamente una operación de canal. se realizará

select { 
case i1 = <-c1: 
    print("received ", i1, " from c1\n") 
case c2 <- i2: 
    print("sent ", i2, " to c2\n") 
case i3, ok := (<-c3): // same as: i3, ok := <-c3 
    if ok { 
     print("received ", i3, " from c3\n") 
    } else { 
     print("c3 is closed\n") 
    } 
} 

En este ejemplo, exactamente una de las operaciones de recepción-de-c1, enviar-a-c2, o recibir-from-c3: Un ejemplo (alteración de la Go language specification). Al ingresar a la selección, se selecciona un canal listo (si lo hay) aleatoriamente. De lo contrario, la operación se bloquea hasta que uno de los canales esté listo.

No conozco ninguna forma trivial de modelar esta selección de canal utilizando las utilidades de Java. Se podría argumentar que esto es una propiedad de la declaración select en lugar del diseño de canales, pero yo diría que es fundamental para el diseño de canales.

+1

Creo que podrías acercarte utilizando el método de encuesta en una cola de bloqueo. Pero tiene razón en que la instrucción select brinda soporte sintáctico para la multiplexación en varios canales diferentes. –

+1

Derecha, no mencioné ocupado-espera porque considero que no es una solución :-). –

2

Se pueden usar de manera similar.

  • Ambos pueden bloquearse al poner/enviar o tomar/recibir.
  • Ambos tienen una capacidad que rige cuando se bloquea el envío.

Las mayores diferencias son probablemente que los canales go son considerablemente más baratos que un objeto java. y que los canales go se pueden restringir solo para enviar o solo recibir, lo que puede garantizar un cumplimiento de tipo adicional con respecto a quién puede enviar y quién puede recibir de un canal.

+1

¿Tiene una fuente para mostrar que son mucho más baratos? No es que no te crea, pero no me sorprendería si algunas de las colas y los canales nio de Java pudieran mantenerse actualizados en términos de tiempo de ejecución. Sin embargo, estoy seguro de que Java pierde en la memoria. –

+0

@ AdamGent Me temo que no tengo ninguna fuente a la mano. Sin embargo, yo estaba hablando principalmente de la memoria, no de la velocidad de ejecución. –

3

Hacer algo similar a la declaración de golang'select en java implicaría usar el paquete java.nio. Específicamente selectores y canales. Echa un vistazo a la documentación del paquete aquí:

http://docs.oracle.com/javase/6/docs/api/java/nio/channels/package-summary.html#multiplex

Ofrece más o menos la misma capacidad que la instrucción de selección golang, utilizando un solo hilo para multiplexar la lectura/escritura de múltiples canales.

+2

Los canales Go permiten la transferencia de estructuras de datos arbitrarios (incluidos los punteros), pero java.nio.channels solo permite la transferencia de bytes. No creo que sean realmente comparables. –

5

Una diferencia más importante es: puede cerrar un canal Ir para indicar que ya no hay más elementos. Eso no es posible usando Java.

Ejemplo: goroutine A lee una lista de archivos. Publica cada archivo en el Canal. Después del último archivo, cierra el canal. goroutine B lee los archivos del canal y los procesa de alguna manera. Después de que el canal está cerrado, el goroutine se cierra.

Hacer esto en Java no es fácil; sin embargo, existen algunas soluciones.

+1

¡De hecho! Esta es una diferencia muy importante. Con Java, debe enviar algún tipo de registro de envenenamiento o carácter de fin de secuencia para indicar que no se recibirán más elementos. Esto requiere código adicional en ambos lados, vea [javadoc de BlockingQueue] (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html): 'una táctica común es para los productores insertar objetos especiales de fin de ciclo o veneno, que se interpretan en consecuencia cuando son tomados por los consumidores. –