2009-09-04 11 views
5

He leído Java Concurrency in Practice y esta es una gran referencia, pero me gustaría ver un resumen conciso de una sola página de los casos de uso del paquete java.util.concurrent.Casos de uso para utilidades concurrentes Java

Por ejemplo:

  • ¿Por qué usar una colección concurrente sobre una colección sincronizada?
  • ¿Cuándo deberían preferirse las clases atómicas sobre el bloqueo explícito?
  • ¿Cuándo se deben usar los bloqueos durante la sincronización?
  • ¿Cuáles son las alternativas para wait() y notify(), notifyAll()?
  • ¿Cuándo se debe utilizar un CompletionService?

¿Cuáles son los pros/contras y las trampas a tener en cuenta?

+0

Esto suena como preguntas de tarea. –

+0

No realmente :) Solo una referencia rápida para elegir la herramienta correcta para el trabajo. – parkr

+0

¿Entonces leyó el libro y todavía tiene estas preguntas? – pek

Respuesta

11
  • ¿Por qué utilizar una colección concurrente sobre una colección sincronizada?

Porque una colección synchronized solo protege los datos contra la corrupción debido al acceso concurrente. Esto no significa que las colecciones synchronized sean optimizadas para el acceso concurrente. Lejos de eso, de hecho, un ConcurrentMap.putIfAbsent es un mecanismo mucho mejor para un compareAndSet que bloquear todo Map para lecturas.

  • ¿Cuándo deberían preferirse las clases atómicas sobre el bloqueo explícito?

Los AtomicInteger y AtomicLong clases deben utilizarse siempre (en mi opinión) sobre el bloqueo a mano con una primitiva porque son más concisa. Considere:

synchronized (lock) { 
    int old = counter; 
    counter++; 
    return old; 
} 

Cuando se compara con:

int old = counter.getAndIncrement(); 

Tengo que decir sin embargo, que las clases sufren de la falta de waitability. Por ejemplo, a menudo quiere algún booleano sincronizado donde wait en la condición booleana. Estos estaban disponibles como WaitableBoolean en la antigua biblioteca de concurrencia de Doug Lea pero se descartaron en j.u.c, no estoy seguro de por qué.

  • ¿Cuándo se deben usar los bloqueos durante la sincronización?

Esta es una pregunta más complicada porque el uso de Locks conlleva una sobrecarga. De hecho, a menudo se dice que no hay ninguna pinta en el uso de ReadWriteLock en casos típicos. Un escenario donde deben usarse bloqueos es donde el bloqueo de un recurso y su desbloqueo no se puede hacer en el mismo alcance léxico. synchronized es impotente para ayudar en casos como estos.

  • ¿Cuáles son las alternativas para wait() y notify(), notifyAll()?

await, signal y signalAll

  • cuándo debe utilizarse un CompletionService?

un servicio de terminación es útil en el caso en que el consumo de un resultado de un cálculo no tiene por qué ser visitada en el punto de presentación de la computación pero donde es importante que la finalización de la computación (o su resultado, o éxito) sea conocido por su programa. Esto podría ser, por ejemplo, para controlar la proporción de tareas fallidas (que arrojó excepciones), o puede ser para la limpieza de recursos.

+0

Un caso de uso para Locks es cuando desea diferentes implementaciones para diferentes clientes. Por ejemplo, un cliente de subprocesos múltiples puede usar un bloqueo estándar, un bloqueo noop de un solo subproceso y, en las pruebas de carga para la detección de condición de anticipación, es posible que desee utilizar un bloqueo que anula el acceso concurrente. – user58804

2
What are the alternatives to wait() and notify(), notifyAll() 

Una muy buena alternativa a wait(), notify() y notifyAll() es no usarlos en absoluto.

200KLOC codebase aquí que es fuertemente multiproceso. Estamos repartir la carga en innumerables núcleos y tienen ejércitos de productores/consumidores esquema etc.

Las instancias de wait(), notify() onotifyAll() en nuestro código?

Zero.

Pongo énfasis en el hecho de que es una aplicación muy multitarea: * pestillos, píldoras de veneno, java.util.concurrent. ** y whatnots en todas partes. Pero wait(), notify() o notifyAll(): cero instancias.

Esto es realmente cosas de bajo nivel que solo deberían tener su uso en utilidades/frameworks de simultaneidad.

De Joshua Bloch, en "Effective Java", en el comienzo de los "hilos" capítulo:

"Si hay una biblioteca que puede salvarlo de hacer bajo multinivel -programación con hebras, por supuesto usarlo ".