23.7 Relación productor/consumidor: 

ArrayBlockingQueue

Una manera de sincronizar los subprocesos productor y consumidor es utilizar las clases del paquete de concu-
rrencia de Java, el cual encapsula la sincronización por nosotros. Java incluye la clase 

ArrayBlockingQueue

 (del 

paquete

java.util.concurrent

); una clase de búfer completamente implementada, segura para los subpro-

cesos, que implementa a la interfaz 

BlockingQueue

. Esta interfaz extiende a la interfaz 

Queue

 que vimos en el 

capítulo 19 y declara los métodos 

put

 y 

take

, los equivalentes con bloqueo de los métodos 

offer

 y 

poll

 de 

Queue

, respectivamente. El método 

put

 coloca un elemento al fi nal del objeto 

BlockingQueue

, y espera si la cola 

está llena. El método 

take

 elimina un elemento de la parte inicial del objeto 

BlockingQueue

, y espera si la co-

la está vacía. Estos métodos hacen que la clase 

ArrayBlockingQueue

 sea una buena opción para implementar un 

búfer compartido. Debido a que el método 

put

 bloquea hasta que haya espacio en el búfer para escribir datos, 

y el método 

take

 bloquea hasta que haya nuevos datos para leer, el productor debe producir primero un valor, 

el consumidor sólo consume correctamente hasta después de que el productor escribe un valor, y el productor 
produce correctamente el siguiente valor (después del primero) sólo hasta que el consumidor lea el valor ante-
rior (o primero). 

ArrayBlockingQueue

 almacena los datos compartidos en un arreglo. El tamaño de este arreglo 

se especifi ca como argumento para el constructor de 

ArrayBlockingQueue

. Una vez creado, un objeto 

Array-

BlockingQueue

 tiene su tamaño fi jo y no se expandirá para dar cabida a más elementos.

El programa de las fi guras 23.16 y 23.17 demuestra a un 

Productor

 y un 

Consumidor

 accediendo a un 

objeto

ArrayBlockingQueue

. La clase 

BuferBloqueo

 (fi gura 23.16) utiliza un objeto 

ArrayBlockingQueue

que almacena un objeto 

Integer

 (línea 7). En la línea 11 se crea el objeto 

ArrayBlockingQueue

 y se pasa 

1

 al 

constructor, para que el objeto contenga un solo valor, como hicimos con el objeto 

BuferSinSincronizacion

de la fi gura 23.14. Observe que en las líneas 7 y 11 utilizamos genéricos, los cuales se describen en los capítu-
los 18 y 19. En la sección 23.9 hablaremos sobre los búferes con varios elementos. Debido a que nuestra clase 

BuferBloqueo

 utiliza la clase 

ArrayBlockingQueue

 (segura para los subprocesos) para administrar el objeto 

al búfer compartido, 

BuferBloqueo

 es en sí segura para los subprocesos, aun cuando no hemos implementado la 

sincronización nosotros mismos.

Figura 23.15

  |  Aplicación con dos subprocesos que manipulan un búfer sin sincronización. (Parte 3 de 3).

Accion                  Valor   Suma producidos   Suma consumidos
------                  -----   ---------------   ---------------
Consumidor lee          -1                       -1 

lee -1 datos incorrectos

Productor escribe        1       1
Consumidor lee           1                        0
Consumidor lee           1                        1 

 1   se lee de nuevo

Consumidor lee           1                        2 

1   se lee de nuevo

Consumidor lee           1                        3 

 1   se lee de nuevo

Consumidor lee           1                        4 

 1   se lee de nuevo

Productor escribe        2       3
Consumidor lee           2                        6
Productor escribe        3       6
Consumidor lee           3                        9
Productor escribe        4      10
Consumidor lee           4                       13
Productor escribe        5      15 
Productor escribe        6      21 

 

 

5   se pierde

Consumidor lee           6                       19

Consumidor leyo valores, el total es 19
Terminando Consumidor
Productor escribe        7      28 

 

 

7   nunca se lee

Productor escribe        8      36 

 

 

8   nunca se lee

Productor escribe        9      45 

 

 

9   nunca se lee

Productor escribe       10      55 

 

 

 10   nunca se lee

Productor termino de producir
Terminando Productor

23.7 Relación 

productor/consumidor: 

ArrayBlockingQueue

949

23_MAQ_CAP_23_DEITEL.indd949

4/19/081:33:45AM