936
Capítulo 23 Subprocesamiento múltiple
los subprocesos de esta forma, podemos asegurar que cada subproceso que accede a un objeto compartido excluye
a los demás subprocesos de hacerlo en forma simultánea; a esto se le conoce como
exclusión mutua
.
Una manera de realizar la sincronización es mediante los
monitores
integrados en Java. Cada objeto tiene un
monitor y un
bloqueo de monitor
(o
bloqueo intrínseco
). El monitor asegura que el bloqueo de monitor de su
objeto se mantenga por un máximo de sólo un subproceso a la vez. Así, los monitores y los bloqueos de monitor
se pueden utilizar para imponer la exclusión mutua. Si una operación requiere que el subproceso en ejecución
mantenga un bloqueo mientras se realiza la operación, un subproceso debe adquirir el bloqueo para poder con-
tinuar con la operación. Otros subprocesos que traten de realizar una operación que requiera el mismo bloqueo
permanecerán bloqueados hasta que el primer subproceso libere el
bloqueo, punto en el cual los subprocesos
bloqueados pueden tratar de adquirir el
bloqueo y continuar con la operación.
Para especifi car que un subproceso debe mantener un bloqueo de monitor para ejecutar un bloque de códi-
go, el código debe colocarse en una
instrucción
synchronized
. Se dice que dicho código está
protegido
por
el bloqueo de monitor; un subproceso debe
adquirir el bloqueo
para ejecutar las instrucciones
synchronized
.
El monitor sólo permite que un subproceso a la vez ejecute instrucciones dentro de bloques
synchronized
que
se bloqueen en el mismo objeto, ya que sólo un subproceso a la vez puede mantener el bloqueo de monitor. Las
instrucciones
synchronized
se declaran mediante la
palabra clave
synchronized
:
synchronized
(
objeto
)
{
Instrucciones
}
// fin de la instrucción synchronized
en donde objeto es el
objeto cuyo bloqueo de monitor se va a adquirir; generalmente, objeto es
this
si es el
objeto en el que aparece la instrucción
synchronized
. Si varias instrucciones
synchronized
están tratando de
ejecutarse en un objeto al mismo tiempo, sólo una de ellas puede estar activa en el objeto; todos los demás subpro-
cesos que traten de entrar a una instrucción
synchronized
en el mismo objeto se colocan en el estado
bloqueado.
Cuando una instrucción
synchronized
termina de ejecutarse, el bloqueo de monitor del objeto se libera y
el sistema operativo puede permitir que uno de los subprocesos
bloqueados, que intentan entrar a una instrucción
synchronized
, adquieran el bloqueo para continuar. Java también permite los
métodos
synchronized
. Dicho
método es equivalente a una instrucción
synchronized
que encierra el cuerpo completo de un método, y que
utiliza a
this
como el objeto cuyo bloqueo de monitor se va a adquirir. Puede especifi car un método como
syn-
chronized
; para ello, coloque la palabra clave
synchronized
antes del tipo de valor de retorno del método en
su declaración.
23.5.1 Cómo compartir datos sin sincronización
Ahora presentaremos un ejemplo para ilustrar los peligros de compartir un objeto entre varios subprocesos sin una
sincronización apropiada. En este ejemplo, dos objetos
Runnable
mantienen referencias a un solo arreglo entero.
Cada objeto
Runnable
escribe cinco valores en el arreglo, y después termina. Tal vez esto parezca inofensivo, pero
puede provocar errores si el arreglo se manipula sin sincronización.
La clase
ArregloSimple
Un objeto de la clase
ArregloSimple
(fi gura 23.7) se compartirá entre varios subprocesos.
ArregloSimple
per-
mitirá que esos subprocesos coloquen valores
int
en
arreglo
(declarado en la línea 7). En la línea 8 se inicializa
la variable
indiceEscritura
, la cual se utilizará para determinar el elemento del arreglo en el que se debe escribir
a continuación. El constructor (líneas 12 a 15) crea un arreglo entero del tamaño deseado.
Figura 23.7
| Clase que administra un arreglo entero para compartirlo entre varios subprocesos. (Parte 1 de 2).
1
// Fig. 23.7: ArregloSimple.java
2
// Clase que administra un arreglo simple para compartirlo entre varios subprocesos.
3
import
java.util.Random;
4
5
public class
ArregloSimple
// PRECAUCIÓN: ¡NO ES SEGURO PARA LOS SUBPROCESOS!
6
{
23_MAQ_CAP_23_DEITEL.indd936
4/19/081:33:39AM