Sie sind auf Seite 1von 7

5 cosas que usted no saba acerca de... java.util.

concurrent, Parte 1 Pgina 1 de 7

developerWorks en espaol Temas Tcnicos tecnologia Java Biblioteca tcnica

5 cosas que usted no saba acerca de...


java.util.concurrent, Parte 1
Programacin multihilos con Colecciones concurrentes
La escritura de cdigo multihilado que tenga buen desempeo y que proteja a las aplicaciones contra
corrupciones es simplemente difcil y es por lo cual tenemos java.util.concurrent. Ted Neward le
muestra cmo las clases de Colecciones concurrentes como CopyOnWriteArrayList, BlockingQueue y
ConcurrentMap , clases estndar de Colecciones modernizadas para sus necesidades de programacin de
concurrencia.

Ted Neward es el director de Neward & Associates, donde hace consultora, es mentor, ensea y hace presentaciones sobre Java,
.NET, XML Services y otras plataformas. Vive en Seattle, Washington.

08-10-2012

Las Colecciones Concurrentes fueron una enorme adicin Acerca de esta serie
As que usted considera que sabe
a Java 5, pero muchos desarrolladores Java les
acerca de programacin Java? El
perdieron de vista con toda la algaraba acerca de hecho es que la mayora de los
anotaciones y genricos. Adicionalmente (y tal vez con desarrolladores rasguan la
mayor sinceridad), muchos desarrolladores evitan este superficie de la plataforma Java,
aprendiendo apenas lo necesario
paquete porque asumen que, tal como los problemas que
para realizar su trabajo. En
pretende resolver, debe ser complicado. estaserie, Ted Neward profundiza
De hecho, java.util.concurrent contiene muchas hacia el ncleo de la funcionalidad
de la plataforma Java para
clases que resuelven efectivamente muchos problemas
descubrir datos poco conocidos que
comunes de concurrencia, sin requerir que usted siquiera pueden ayudarle a resolver incluso
sude una gota. Contine leyendo para conocer cmo las los desafos de programacin ms
clases java.util.concurrent como complicados.

CopyOnWriteArrayList y BlockingQueue le ayudan a


resolver los desafos perniciosos de la programacin multihilos.

1. TimeUnit
Aunque no es una clase Collections per se, la Desarrolle habilidades de este
enumeracinjava.util.concurrent.TimeUnit hace tema
Este contenido es parte de
que el cdigo sea mucho ms fcil de leer. knowledge paths progresivo para
UtilizarTimeUnit libera a los desarrolladores que usan su avanzar en sus habilidades. Vea:
mtodo o API de la tirana del milisegundo. Convirtase en desarrollador Java
Concurrencia Java
TimeUnit incorpora todas las unidades de tiempo,
variando desde MILLISECONDS y MICROSECONDS hasta
https://www.ibm.com/developerworks/ssa/java/library/j-5things4/ 17/05/2017
5 cosas que usted no saba acerca de... java.util.concurrent, Parte 1 Pgina 2 de 7
DAYS y HOURS, lo cual significa que maneja casi todos rangos de tiempo que un
desarrollador puede necesitar. Y, gracias a los mtodos de conversin declarados en la
enumeracin, incluso es trivial convertir HOURS enMILLISECONDS cuando el tiempo se
acelera.

2. CopyOnWriteArrayList
Crear una copia fresca de un array es una operacin demasiado costosa, en trminos
tanto de tiempo como de sobrecosto de memoria, como para considerarla para uso
ordinario; en su lugar, los desarrolladores a menudo usan como recurso ArrayList . Sin
embargo, esa tambin es una opcin costosa, porque cada vez que usted itera en el
contenido de la coleccin, debe sincronizar todas las operaciones, incluyendo lectura y
escritura, para garantizar la consistencia.

Esto representa un retroceso en la estructura de costos para escenarios donde numerosos


lectores estn leyendo la ArrayList pero cuando pocos la estn modificando.

CopyOnWriteArrayList es la pequea joya asombrosa que resuelve este problema. Su


Javadoc define a CopyOnWriteArrayList como una "variante de hebra segura de
ArrayList en la cual todas las operaciones (aadir, configurar, etc.) son implementadas
mediante la creacin de una copia fresca del array".

La coleccin copia internamente su contenido sobre un nuevo array tras cualquier


modificacin, de manera que los lectores que acceden al contenido del array no incurren
en costos de sincronizacin (pues nunca estn operando sobre datos mutables).

Esencialmente, CopyOnWriteArrayList es ideal para el escenario exacto donde


ArrayList nos falla: colecciones de lectura-frecuente y escritura-ocasional como las
Listener para un evento JavaBean.

3. BlockingQueue
La interfaz BlockingQueue establece que es una Queue, Lo cual significa que sus
elementos se almacenan en un pedido tipo primero en entrar, primero en salir (FIFO). Los
elementos insertados en un pedido en particular son recuperados en ese mismo pedido
pero con la garanta adicional de que cualquier intento de recuperar un elemento de una
cola vaca bloquear la hebra de llamada hasta que el elemento est listo para ser
recuperado. De igual forma, cualquier intento de insertar un elemento dentro de una cola
que est llena bloquear la hebra de llamada hasta que haya espacio disponible en el
almacenamiento de la cola.

BlockingQueue resuelve pulcramente el problema de cmo "entregar" elementos


reunidos por una hebra a otra hebra para su procesamiento, sin una preocupacin
explcita por problemas de sincronizacin. La pista Guarded Blocks del Tutorial Java es un

https://www.ibm.com/developerworks/ssa/java/library/j-5things4/ 17/05/2017
5 cosas que usted no saba acerca de... java.util.concurrent, Parte 1 Pgina 3 de 7
buen ejemplo. Esta construye un almacenamiento intermedio vinculado de ranura
individual usando sincronizacin manual y wait()/notifyAll() para sealar entre
hebras cuando haya un nuevo elemento disponible para consumo, y cuando la ranura est
lista para ser llenada con un nuevo elemento. (Vea la seccin implementacin de Guarded
Blocks para ms detalles).

A pesar del hecho de que el cdigo del tutorial de Guarded Blocks funciona, este es
extenso, desordenado y no es del todo intuitivo. Regresando a los primeros das de la
plataforma Java, s, los desarrolladores Java tenan que enredarse con dicho cdigo, pero
estamos en el 2010 seguramente las cosas han mejorado?

El Listado 1 muestra una versin reescrita de cdigo Guarded Blocks donde he empleado
ArrayBlockingQueue en lugar del manualmente escrito Drop.
Listado 1. BlockingQueue
import java.util.*;
import java.util.concurrent.*;

class Producer
implements Runnable
{
private BlockingQueue<String> drop;
List<String> messages = Arrays.asList(
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"Wouldn't you eat ivy too?");

public Producer(BlockingQueue<String> d) { this.drop = d; }

public void run()


{
try
{
for (String s : messages)
drop.put(s);
drop.put("DONE");
}
catch (InterruptedException intEx)
{
System.out.println("Interrupted! " +
"Last one out, turn out the lights!");
}
}
}

class Consumer
implements Runnable
{
private BlockingQueue<String> drop;
public Consumer(BlockingQueue<String> d) { this.drop = d; }

public void run()


{
try
{
String msg = null;
while (!((msg = drop.take()).equals("DONE")))
System.out.println(msg);
}
catch (InterruptedException intEx)
{
System.out.println("Interrupted! " +
"Last one out, turn out the lights!");
}
}
}

public class ABQApp


{
public static void main(String[] args)
{
BlockingQueue<String> drop = new ArrayBlockingQueue(1, true);
(new Thread(new Producer(drop))).start();
(new Thread(new Consumer(drop))).start();
}
}

El ArrayBlockingQueue tambin honra lo "justo" queriendo decir que puede


proporcionar acceso de hebras de lector y grabador del tipo primera en entrar, primera en

https://www.ibm.com/developerworks/ssa/java/library/j-5things4/ 17/05/2017
5 cosas que usted no saba acerca de... java.util.concurrent, Parte 1 Pgina 4 de 7
salir. La alternativa sera una poltica ms eficiente que corra el riesgo de privar de
recursos a algunas hebras. (Esto es, sera ms eficiente permitir a los lectores ejecutarse
mientras otros lectores mantienen el bloqueo, pero usted se arriesga a un flujo constante
de hebras de lectura evitando que el grabador realice su trabajo).

BlockingQueue tambin soporta mtodos que toman un Cuidado con los errores!
Por cierto, usted est en lo cierto si
parmetro de tiempo que indica cunto tiempo debe
not que Guarded Blocks contiene
bloquearse la hebra antes de retornar a la falla de seal un error enorme qu pasara si
para insertar o recuperar el elemento en cuestin. Hacer un desarrollador sincroniza en la
esto evita una espera desvinculada, la cual podra ser la instancia Drop dentro de main()?

muerte de un sistema de produccin, pues una espera


desvinculada puede convertirse muy fcilmente en un sistema colgado haciendo necesario
un reinicio.

4. ConcurrentMap
Map aloja un error sutil de concurrencia que ha llevado a muchos desarrolladores Java
incautos a perderse. ConcurrentMap es la solucin fcil.

Cuando se accede a un Map desde mltiples hebras, es comn usar containsKey() o


get() para encontrar si una clave dada est presente antes de almacenar el par de
clave/valor. Pero incluso con un Map sincronizado, alguna hebra podra escabullirse
durante este proceso y tomar el control del Map. El problema es que el bloqueo es
adquirido al inicio delget() y luego liberado antes de que el bloqueo se pueda adquirir de
nuevo, en la llamada a put(). El resultado es una condicin de actualizacin: es una
competencia entre las dos hebras y el resultado ser diferente dependiendo de cul llegue
primero.

Si dos hebras llaman un mtodo exactamente al mismo tiempo, cada una realizar prueba
y cada una realizar put, perdindose en el proceso el valor de la primera hebra.
Afortunadamente, la interfaz ConcurrentMap soporta cierto nmero de mtodos
adicionales que estn diseados para hacer dos cosas bajo un bloqueo individual:
putIfAbsent(), por ejemplo, realiza la primera prueba y luego realiza un put solo si la
clave no est almacenada en el Map.

5. SynchronousQueues
SynchronousQueue es una criatura interesante, segn el Javadoc:
Es una cola de bloqueo en la cual cada operacin de insercin debe esperar por una
operacin de eliminacin correspondiente de otra hebra y viceversa. Una cola sincronizada
no tiene ninguna capacidad interna, ni siquiera la capacidad de una.
Esencialmente, SynchronousQueue es otra implementacin de la anteriormente
mencionada BlockingQueue. Esta nos proporciona una forma extremadamente ligera de

https://www.ibm.com/developerworks/ssa/java/library/j-5things4/ 17/05/2017
5 cosas que usted no saba acerca de... java.util.concurrent, Parte 1 Pgina 5 de 7
intercambiar elementos de una hebra a otra usando la semntica de bloqueo usada
porArrayBlockingQueue. En el Listado 2, reescrib el cdigo del Listado 1 usando
SynchronousQueue en lugar de ArrayBlockingQueue:
Listado 2. SynchronousQueue
import java.util.*;
import java.util.concurrent.*;

class Producer
implements Runnable
{
private BlockingQueue<String> drop;
List<String> messages = Arrays.asList(
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"Wouldn't you eat ivy too?");

public Producer(BlockingQueue<String> d) { this.drop = d; }

public void run()


{
try
{
for (String s : messages)
drop.put(s);
drop.put("DONE");
}
catch (InterruptedException intEx)
{
System.out.println("Interrupted! " +
"Last one out, turn out the lights!");
}
}
}

class Consumer
implements Runnable
{
private BlockingQueue<String> drop;
public Consumer(BlockingQueue<String> d) { this.drop = d; }

public void run()


{
try
{
String msg = null;
while (!((msg = drop.take()).equals("DONE")))
System.out.println(msg);
}
catch (InterruptedException intEx)
{
System.out.println("Interrupted! " +
"Last one out, turn out the lights!");
}
}
}

public class SynQApp


{
public static void main(String[] args)
{
BlockingQueue<String> drop = new SynchronousQueue<String>();
(new Thread(new Producer(drop))).start();
(new Thread(new Consumer(drop))).start();
}
}

El cdigo de implementacin se ve casi idntico, pero la aplicacin tiene un beneficio


agregado en cuanto a que SynchronousQueue permitir una insercin en la cola solo si
hay una hebra esperando a consumirla.

En la prctica, SynchronousQueue es similar a los "canales rendezvous" disponibles en


lenguajes como Ada o CSP. Estos tambin se conocen algunas veces como "uniones" en
otros entornos, incluyendo .NET (vea Recursos).

En conclusin

https://www.ibm.com/developerworks/ssa/java/library/j-5things4/ 17/05/2017
5 cosas que usted no saba acerca de... java.util.concurrent, Parte 1 Pgina 6 de 7
Por qu luchar introduciendo concurrencia en sus clases Collections cuando la biblioteca
de tiempo de ejecucin Java ofrece equivalentes tiles y pre elaborados? El siguiente
artculo de esta serie explora an ms el java.util.concurrent namespace.

Descargar
Descripcin Nombre tamao

Sample code for this article j-5things4-src.zip 23KB

Recursos Comienza a utilizar IBM


Aprender Bluemix
Guas rpidas de inicio y
"Java theory and practice: Concurrent collections classes" (Brian demos de la plataforma
abierta en la Nube de IBM.
Goetz, developerWorks, julio del 2003): Conozca cmo el paquete
util.concurrent de Doug Lea revitaliza los tipos estndar de la Sbete a la Nube de IBM
Abre el potencial del
coleccin List y en el Map.
cmputo en la nube con
productos y servicios de IBM.
Java Concurrency in Practice (Brian Goetz, et. al. Addison-Wesley,
2006): La notable habilidad de Brian para destilar conceptos Arquitectura de Nube
complejos para los lectores hace de este libro una obligacin en la Abierta de IBM
Al cambiar cmo se manejan
biblioteca de cualquier desarrollador Java. los negocios y la sociedad, la
computacin en nube est
"Spice up collections with generics and concurrency" (John abriendo gigantescas
Zukowski, developerWorks, abril del 2008): Presenta los cambios a avenidas de innovaciones.
Java Collections Framework en Java 6.
Package java.util.concurrent, Java platform SE 6: Aprenda ms
acerca de las clases de herramientas que se tratan en este
artculo.
Guarded Blocks: El modismo ms comn para coordinar hebras.
"Introduction to the Collections Framework" (MageLang Institute,
Sun Developer Network, 1999): Este antiguo pero buen tutorial es
una introduccin completa a Java Collections Framework, antes de
las colecciones concurrentes.
"The Collections Framework": Lea la documentacin de Java
Collections Framework y la API de Sun Microsystems.
The Joins Concurrency Library: Microsoft Research public esta
biblioteca implementando el concepto joins como un mecanismo
de sincronizacin; el documento de investigacin asociado (en
PDF) es una buena fuente para aprender acerca de la teora que
hay detrs de las uniones (joins).
El rea zona de tecnologa developerWorks Java: Cientos de
artculos acerca de cada aspecto de la programacin Java.

Comentar

https://www.ibm.com/developerworks/ssa/java/library/j-5things4/ 17/05/2017
5 cosas que usted no saba acerca de... java.util.concurrent, Parte 1 Pgina 7 de 7
Participe en la Comunidad My developerWorks.

https://www.ibm.com/developerworks/ssa/java/library/j-5things4/ 17/05/2017

Das könnte Ihnen auch gefallen