Control de la concurrencia en Java (API alto nivel)
Disponible a partir de Java 5, mejoras respecto a los mecanismos previos de control de la concurrencia.
- Generan menos sobrecarga en tiempo de ejecución
- Permiten controlar la e.m. y la sincronización a un nivel más fino
- Soporta primitivas clásicas como los semáforos o las variables de condición en monitores
- Ofrece cerrojos con mejor soporte a granularidad y al ámbito de uso
API java.util.concurrent.atomic
Conjunto de clases que soportan programación concurrente segura sobre variables simples tratadas de forma atómica.
Clases: AtomicBoolean, AtomicInteger, AtomicIntegerArray, AtomicLong, AtomicLongArray, AtomicReference<V>
, etc
OJO, no todos los métodos del API de estas clases soportan concurrencia segura. Sólo aquellos en los que se indica que la operación se realiza de forma atómica
La clase Semaphore
Permite disponer de semáforos de conteo de semántica mínima o igual a la estándar de Dijkstra, o aumentada.
Métodos principales
Semaphore(long permits)
acquire(), acquire(int permits)
, equivale a waitrelease(), release(long permits)
, equivale a signaltryAcquire()
, varias versionesavailablePermits()
La clase CyclicBarrier
Una barrera es un punto de espera a partir del cuál todos los hilos se sincronizan. Ningún hilo pasará por la barrera hasta que todos los hilos esperados llegan a ella.
Nos pertmite unificar resultados parciales e iniciar la siguiente fase de una ejecución simutánea.
API java.util.concurrent.locks
Proporciona clases para establecer sincronización de hilos alternativas a los bloques de código sincronizado y a los monitores.
Clases e interfaces de interés
-
ReentrantLock
, proporciona cerrojos de e.m. de semántica equivalente asynchronized
, pero con un manejo más sencillo y una mejor granularidad -
LockSupport
, proporciona primitivas de bloqueo de hilos que permiten al programador diseñar sus clases de sincronización y cerrojos propios -
Condition
, es una interfaz cuyas instancias se usan asociadas alocks
. Implementan variables de condición y proporcionan una alternativa de sincronización a los métodoswait
,notify
ynotifyAll
de la claseObject
API de la clase ReentrantLock
Proporciona cerrojos reentrantes de semántica equivalente a synchronized
.
Métodos:
lock(), unlock(), isLocked()
Métododo Condition newCondition()
retorna una variable de condición asociada al cerrojo.
Interfaz Condition
Proporciona variables de condición, se usa asociada a un cerrojo, siendo cerrojo
una instancia de la clase ReentrantLock
cerrojo.newCondition()
retorna la variable de condición.
Métodos sobre las variables de condición:
await(), signal(), signalAll()
Clases contenedoras sincronizadas
A partir de Java 5 se incorporan versiones sincronizadas de las principales clases contenedoras.
Clases: ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet, CopyOnWriteArrayList y CopyOnWriteArraySet
.
Colas sincronizadas
A partir de Java 5 se incorporan diferentes versiones de colas, todas ellas sincronizadas.
Clases: LinkedBlockingQueue, ArrayBlockingQueue, SynchronousQueue, PriorityBlockingQueue y DelayQueue
Características
Son seguras frente a hilos concurrentes, proporcionan notificación a hilos según cambia su contenido.
Son autosincronizadas, proveen sincronización (además de e.m.) por sí mismas.
Facilitan enormemente la programación de patrones de concurrencia como el P-S.
Uso correcto de colecciones
Usamos colecciones a través de interfaces (usabilidad del código)
Colecciones no sincronizadas no mejora mucho el rendimiento, para problemas como productor-consumidor: use colas.
Minimice la sincronización explícita, si con una colección retarda sus algoritmos, distribuya los datos y use varias.