4.4 Sincronizacion de Hilos
4.4 SINCRONIZACIÓN DE HILOS
Cuando se están utilizando hilos múltiples, algunas veces es necesario coordinar las actividades de dos o más. El proceso por el cual se logra esto se llama sincronización. La razón más común para la sincronización es cuando dos o mas hilos necesitan acceso a un recurso compartido que sólo puede ser utilizado por un hilo a la vez. Otra razón para la sincronización es cuando un hilo está esperando un evento causado por otro hilo. En este caso, debe de haber algún medio por el cual el primer hilo se mantenga en estado suspendido hasta que el evento ocurra.
La sincronización esta soportada por la palabra clave synchronized y por unos cuantos métodos bien definidos que tienen todos los objetos.
USO DE MÉTODOS SYNCHRONIZED
Cuando se llama al método Synchronized , el hilo que llama ingresa al monitor de objeto, que entonces bloquea el objeto. Mientras esta bloqueado ningún otro hilo puede ingresar al método, ni ingresar algún otro método sincronizado definido por el objeto. Cuando el hilo retorna del método, el monitor desbloquea el objeto permitiendo que sea usado por el próximo hilo.
Los puntos clave de un método sincronizado son:
- · Un método sincronizado se crea precediendo su declaración con synchronized
- · Para cualquier objeto dado,una vez un método sincronizado ha sido llamado se bloquea el objeto, y los métodos no sincronizados dentro del mismo objeto pueden ser utilizados por otros hilos en ejecución.
- · Otros hilos que traten de llamar un objeto sincronizado en uso ingresaría en un estado de espera, hasta que el objeto se desbloquea.
- · Cuando un hilo sale del método sincronizado, el objeto se desbloquea.
DECLARACIÓN SYNCHRONIZED
La creación del método Synchronized dentro de las clases creadas por nosotros mismos es fácil y eficiente sin embargo no trabaja en todos los casos. Por ejemplo, podemos querer sincronizar el acceso a algún método que no este modificado por Synchronized ; esto ocurre cuando queremos utilizar una clase que no fue creada por nosotros sino por un tercero, y no tenemos acceso al código fuente.
La solución para este problema es poner llamadas a los métodos definidos por esa clase dentro de un bloque Synchronized. La forma general de un bloque Synchronized es:
synchronized (objeto){
//declaraciones para ser sincronizadas
synchronized (objeto){
//declaraciones para ser sincronizadas
}
Aquí objeto hace referencia al objeto que va a ser sincronizado. Un objeto sincronizado asegura que una llamada a un método, ocurra solo después de que el hilo que llama ha ingresado al monitor del objeto.
EJEMPLO:
/**
uso de synchronized en el control de accesos
*/
class SumArray {
private int sum;
synchronized int
SumArray(int nums[]){
sum=0;
//inicializa sum
for (int i=0;i<nums.length;i++){
sum= nums[i];
System.out.println ("Ejecucion total para" +
Thread.currentThread().getName() + " es " + sum);
try{
Thread.sleep(10); //permite el suicheo de tareas
}
catch (InterruptedException
exc){
System.out.println ("Hilo principal interrumpido ");
}
}
return sum;
}
}
class MyThread implements Runnable{
Thread thrd;
static SumArray sa=new SumArray();
int
a[];
int answer;
/ /contruye un nuevo hilo
MyThread(String name,int nums[]){
thrd= new Thread (this,name);
thrd.start();
//arranca el hilo
a= nums;
}
//inicia la ejecucion del nuevo hilo
public void
run(){
int sum;
System.out.println ("Suma para " + thrd.getName() + " es "
+ answer);
System.out.println (thrd.getName() + "terminando");
}
}
class Sync{
public static void main
(String[] args) {
int a[]={1,2,3,4,5};
MyThread mt1= new
MyThread ("Hijo #1",a);
MyThread mt2= new
MyThread ("Hijo #2",a);
}
}
El programa anterior crea 3 clases. La primera es SumArray que contiene el método
SumArray (), que suma un arreglo entero. La segunda clase es MyThread, que
utiliza un objeto de tipo SumArray para obtener la suma de un arreglo entero.
Finalmente, la clase Sync crea dos hilos, y permite que ellos calculen la suma
de un arreglo entero.
Dentro de sumArray (), se llama sleep() para permitir que ocurra
un cambio de tarea, pero de hecho no es posible. Porque sumArray () está
sincronizada. Solamente un hilo a la vez puede utilizarla. De modo que cuando
el segundo hilo hijo comience su ejecución, no ingresa sumArray()
hasta después que el primer hilo hijo esté terminado. Esto asegura que
se produzca el resultado correcto.
Sincronización
Vídeo
Sincronización
Vídeo
Comentarios
Publicar un comentario