Anda di halaman 1dari 7

CCP

Procesamiento paralelo con hilos de


Java
Tabla de contenidos
1. Soporte para hilos en Java ...................................................................................................... 1
2. Creacin y control de un hilo .................................................................................................. 2
2.1. Mtodos de creacin de un hilo ..................................................................................... 2
2.2. Control de hilos mediante mtodos de Thread .................................................................. 2
3. Sincronizacin por exclusin mutua ......................................................................................... 2
3.1. Sincronizacin de mtodos ........................................................................................... 2
3.2. Sincronizacin de bloques ............................................................................................ 3
3.3. Sincronizacin de mtodos y bloques estticos ................................................................. 3
4. Espera y notificacin de eventos .............................................................................................. 3
4.1. Wait y notify ............................................................................................................. 3
4.2. NotifyAll .................................................................................................................. 4
4.3. Wait y sleep .............................................................................................................. 4
4.4. Wait y notify en mtodos estticos ................................................................................. 4
5. La integral numrica con hilos ................................................................................................. 4
5.1. Diseo ..................................................................................................................... 4
5.2. La clase NumIntegralTh .............................................................................................. 4
5.3. La clase IntervalTh ..................................................................................................... 5
5.4. La clase IntegralRes .................................................................................................... 6
5.5. Versin en C ............................................................................................................. 6
5.6. Tiempos de ejecucin .................................................................................................. 7
Bibliografa .............................................................................................................................7

1. Soporte para hilos en Java


En Java el soporte a la concurrencia (paralelismo) basado en hilos se hace en el propio lenguaje y no en base a
una librera auxiliar (p.ej. PThreads, hilos win32).
El soporte de Java a los hilos se hace mediante los siguientes elementos:

Dotando a la clase ancestral Object de los mtodos Wait(), Notify() y NotifyAll() que dan soporte a los
eventos

Asociando un lock a cada clase y a cada objeto, la obtencin y la devolucin del lock se hace mediante la
utilizacin de la palabra reservada synchronized mediante la cual se definen mtodos o bloques de cdigo a
los que se accede en exclusin mutua

Proporcionando la clase Thread en la librera java.lang que implementa los mecanismos bsicos para realizar
hilos

La interfaz Runnable permite la creacin de hilos en clases que extienden otra clase diferente de Thread

Otras funcionalidades disponibles son:

El control de prioridad

La posibilidad de limitar el nmero de hilos activos mediante la clase ThreadPool

La posibilidad de controlar grupos de hilos mediante la clase ThreadGroup


IV-A.1

Procesamiento paralelo con hilos de Java

CCP

2. Creacin y control de un hilo


2.1. Mtodos de creacin de un hilo
En Java se puede crear un hilo mediante dos mecanismos:

Extendiendo la clase Thread

Implementado la interfaz Runnable

Tanto Thread como Runnable forman parte de java.lang con lo que no requieren ser importados explcitamente.
Ambos mtodos tienen en comn el procedimiento bsico que consiste en implementar el mtodo run(). El mtodo para iniciar el hilo depende de la forma como se halla creado:

Extendiendo la clase Thread Se llama al mtodo start de los objetos que instancian la clase

Implementando Runnable Se crea un objeto Thread con el constructor que tiene como parmetro un objeto
Runnable y llamando posteriormente al mtodo start de dicho objeto

En las pginas 15-23 se dispone de un ejemplo en el que se incluye una animacin en un Applet utilizando los
dos mecanismos: una clase auxiliar que extiende Thread e implementando Runnable en el propio Applet.

2.2. Control de hilos mediante mtodos de Thread


La clase Thread contiene una serie de mtodos que permiten controlar el funcionamiento de los hilos:

isAlive Devuelve un valor true si el hilo esta activo, es decir su mtodo run ha sido iniciado con start y todava no ha finalizado

join Condiciona la continuacin del hilo actual a la terminacin de otro hilo, la duracin de esta espera se
puede limitar

setName y getName Permiten dar un nombre a un hilo y obtener dicho nombre, respectivamente. Esto tiene
inters sobre todo para la depuracin. La funcin setName se puede evitar utilizando los constructores adecuados de Thread (pag 30)

Tambin se dispone de los siguientes mtodos estticos:

sleep Detiene la ejecucin del hilo que hace la llamada durante el tiempo que se especifica

currentThread Permite identificar al hilo que hace la llamada (ejemplo en la pgina 31)

enumerate Devuelve una matriz con referencias a todos los hilos creados por el programa (no necesariamente activos) y su nmero

activeCount Devuelve el nmero de hilos creados por el programa (no necesariamente activos)

3. Sincronizacin por exclusin mutua


3.1. Sincronizacin de mtodos
La ejecucin de mtodos de un objeto se puede forzar a que se haga en exclusin mutua utilizando la palabra reIV-A.2

CCP

Procesamiento paralelo con hilos de Java

servada synchronized en la declaracin del mtodo (pag 45)


Este mecanismo asegura que la modificacin del estado del objeto se realiza de forma consistente evitando las
condiciones de carrera ya que solamente un objeto puede estar ejecutando en un momento dado un mtodo sincronizado, o sea que no puede haber simultneamente dos o mas objetos ejecutando mtodos sincronizados (el
mismo mtodo o diferentes mtodos) de forma simultnea.
Esta serializacin del acceso a los mtodos sincronizados asegura la evitacin de condiciones de carrera, aunque
por otra parte reduce las posibilidades de paralelismo en la utilizacin del objeto.
El funcionamiento de esto consiste en que al iniciar un mtodo sincronizado se toma el lock asociado al objeto y
al finalizar se devuelve el lock dejndolo disponible.

3.2. Sincronizacin de bloques


Con el fin de reducir el efecto de la serializacin de cdigo sincronizado sobre el paralelismo, se puede hacer
uso de la sincronizacin de bloque que resulta ms flexible:

Permite serializar segmentos de cdigo dentro de un mtodo

Permite elegir el objeto cuyo lock se va a utilizar en la sincronizacin (no ha de ser necesariamente this)

Un ejemplo de sincronizacin de un bloque aparece la pgina 55.


syncrhonized(obj) {
...
...
}

Hay que evitar que el objeto cuyo lock se utiliza en synchonized sea null, y tambin tener cuidado ya que las referencias a objetos pueden cambiar en tiempo de ejecucin y por tanto los efectos sobre la sincronizacin pueden generar errores.

3.3. Sincronizacin de mtodos y bloques estticos


Los mtodos estticos tambin pueden sincronizarse ya que cada clase tiene asociado tambin un lock, que en
realidad es el lock del objeto de tipo Class asociado a la clase y que puede obtenerse explcitamente mediante:
Class classobj = Class.forName("Nombre_de_la_clase");

Los bloques de cdigo dentro de un mtodo esttico pueden sincronizarse haciendo uso del objeto mencionado:
public class Ejemplo {
void proceso() {
....
synchronized (Class.forName("Ejemplo")) {
.....
}
....
}
}

4. Espera y notificacin de eventos


4.1. Wait y notify
El mecanismo de espera y notificacin viene proporcionado en Java en la clase ancestra Object, este mecanismo
evita la espera ocupada de un hilo respecto de un cambio que ha de producir otro hilo. El primero hace una espera no ocupada (wait) y el segundo una notificacin (notify).

IV-A.3

Procesamiento paralelo con hilos de Java

CCP

Ambos mtodos han de llamarse desde cdigo sincronizado con el mismo lock para asegurar que el test de la
condicin y la entrada en espera se realizan en exclusin mutua. La funcin wait() libera el lock antes de iniciar
la espera y retoma el lock despus de recibir la notificacin.
En las pginas 67-68 se tiene una versin de un semforo con espera ocupada para la operacin get. La versin
con wait de la pgina 70 evita la espera ocupada y requiere sincronizar el mtodo. Obsrvese que wait est en un
bucle en el que despus de salir de wait se vuelve a testear la condicin.

4.2. NotifyAll
Cuando hay varios hilos en espera de la misma condicin no es posible saber cual de ellos recibir la notificacin.
El mtodo NotifyAll permite notificar a todos los hilos en espera que han utilizado el mismo lock, ser el mismo
lock que se ha utilizado para sincronizar el cdigo que incluye la llamada a NotifyAll.
En la pgina 75 se tiene la clase ResourceThrottle como ejemplo de utilizacin de NotifyAll. Todos los hilos
son notificados pero slo uno de los que demandan un nmero igual o menor de los recursos disponibles saldr
de la espera.
En las pginas 76-77 se tiene la clase TargetNotify que implementa un mecanismo de espera y notificacin selectivo.

4.3. Wait y sleep


El mtodo wait tiene una versin que permite fijar un timeout en milisegundos, al cabo del cual es hilo retoma la
ejecucin aunque no se haya producido la notificacin.
Esta versin de wait funciona como sleep con la diferencia de que wait no retiene el lock, por lo que se puede
utilizar dentro de un mtodo sincronizado a diferencia de sleep.

4.4. Wait y notify en mtodos estticos


Wait y notify son mtodos no estticos por lo que no se pueden llamar dentro de mtodos estticos.
Sin embargo, se pueden utilizar los mtodos wait y notify asociados a un objeto esttico como en el ejemplo
MyStaticClass de la pgina 86 que ofrece los mtodos staticWait y staticNotify que pueden utilizarse en mtodos estticos.

5. La integral numrica con hilos


5.1. Diseo
Para hacer la integral numrica con hilos de Java se han utilizado tres clases

La clase NumIntegralTh que es la clase principal con el mtodo main que lanza los hilos

La clase IntervalTh que define cada hilo

La clase IntegralRes que define el acceso al resultado total en exclusin mutua

5.2. La clase NumIntegralTh


package ccpthreads;
import java.io.*;
public class NumIntegralTh {

IV-A.4

CCP

Procesamiento paralelo con hilos de Java

public static void main(String[] args) {


double a = 0.0;
double b = 0.0;
int n = 0;
int p = 0;
IntervalTh intervalTh[];
IntegralRes res = new IntegralRes();
long t0, t1;
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
System.out.println ("Enter a, b, n and p ");
try {
Double A = new Double(input.readLine());
a = A.doubleValue();
Double B = new Double(input.readLine());
b = B.doubleValue();
Integer N = new Integer(input.readLine());
n = N.intValue();
System.out.println(n);
Integer P = new Integer(input.readLine());
p = P.intValue();
} catch (IOException e) {
System.out.println (e.getMessage());
}
intervalTh = new IntervalTh[p];
for (int i=0; i<p; i++) intervalTh[i] = new IntervalTh(i, a, b, n, p, res);
t0 = System.currentTimeMillis();
for (int i=0; i<p; i++) intervalTh[i].start();
try {
for (int i=0; i<p; i++) intervalTh[i].join();
} catch (InterruptedException e) {
System.out.println (e.getMessage());
}
t1 = System.currentTimeMillis();
System.out.println ("El valor de la integral es "+res.get());
System.out.println ("El tiempo transcurrido es: "+ (t1-t0));
}
}

5.3. La clase IntervalTh


package ccpthreads;
public class IntervalTh extends Thread {
int id;
double a, b;
int n, p;
IntegralRes res;
public IntervalTh(int id, double a, double b, int n, int p, IntegralRes res) {
this.id = id;
this.a = a;
this.b = b;
this.n = n;
this.p = p;
this.res = res;
}
private double f(double x) {
double y;
y = Math.log(Math.sin(x*x+1));
y = Math.sqrt(y*y);
return y;
}
private double Trap (double a, double b, int n, double h) {
double integral;
double x;
int i;
integral = (f(a) + f(b)) / 2.0;
x = a;
for (i=1; i<n; i++) {
x = x + h;
integral = integral + f(x);
}
integral = integral*h;

IV-A.5

Procesamiento paralelo con hilos de Java

CCP

return integral;
}
public void run() {
double h;
double local_a;
double local_b;
int local_n;
double integral;
h = (b - a)/(double)n;
local_n = n / p;
local_a = a + (double)id * local_n * h;
local_b = local_a + local_n * h;
integral = Trap (local_a, local_b, local_n, h);
res.update(integral);
}
}

5.4. La clase IntegralRes


package ccpthreads;
public class IntegralRes {
private double total;
public IntegralRes() {
total = 0;
}
public synchronized void update (double v) {
total = total + v;
}
public synchronized double get() {
return total;
}
}

5.5. Versin en C
#include <stdio.h>
#include <time.h>
#include <math.h>
double f(double x) {
double y;
y = log(sin(x*x+1));
y = sqrt(y*y);
return y;
}
int main(int argc, char* argv[]) {
double integral;
float a;
float b;
int n;
double h;
double x;
int i;
clock_t t0, t1;
float t;
a = 0.0; b = 0.0; n = 0;
printf ("Enter a, b and n\n");
scanf ("%f %f %d", &a, &b, &n);
printf ("of the integral from %f to %f\n", a, b);
t0 = clock();
h = ((double)b-(double)a)/(double)n;
integral = (f(a) + f(b)) / 2.0;
x = a;
for (i=1; i<n-1; i++) {
x = x + h;
integral = integral + f(x);

IV-A.6

CCP

Procesamiento paralelo con hilos de Java

}
integral = integral * h;
t1 = clock();
t = (float)((1000*t1)/CLOCKS_PER_SEC) - (float)((1000*t0)/CLOCKS_PER_SEC);
printf ("With n = %d trapezoids, our estimate\n", n);
printf ("of the integral from %f to %f = %20.20f\n", a, b, integral);
printf ("Tiempo = %f\n", t);
return 0;
}

5.6. Tiempos de ejecucin


Tabla 1. a = 0.0, b = 1.0, n = 10000000, p = 4
Sistema

Secuencial (C)

Secuencial (Java)

Paralelo

Origin 2000

7770

19588

4793

Athlon 1.7GHz linux

3620

1774

Bibliografa
Scott Oaks, Henry Wong "Java Threads" O'Reilly
Doug Lea "Concurrent Programming in Java: Design Principles and Patterns" Addison-Wesley

IV-A.7

Anda mungkin juga menyukai