Curso JAVA
Unidad 5: "Threads y
multitarea"Objetivos de la Unidad:
1.- Programaci�n modular
cl�sica
2.- Programaci�n con Threads
("Hilos")
3.- Conversi�n de una llamada a funci�n normal a una multithread
Supongamos que disponemos de una funci�n denominada servicio tal como:
void
servicio(String s, int a, boolean b)
{
<c�digo de
servicio>
}
Una llamada a la funci�n
servicio ser�a:
...
servicio("Hola", 5, true);
...
En este caso la l�nea siguiente a la llamada no se ejecutar� hasta que servicio devuelva el control.
En programaci�n multithread
podr�amos escribir lo siguiente:
...
new Servicio("Hola", 5, true);
...
En este caso la l�nea siguiente a la llamada se
ejecutar� independientemente (en paralelo) con el thread de
Servicio.
La t�cnica para pasar de la primera forma a la segunda consiste en mapear el constructor de Thread con los mismos par�metros, de modo que la clase Servicio quedar�a como sigue:
class Servicio extends
Thread
{
String s;
int a;
boolean b;
Servicio(String s, int a, boolean b)
{
this.s = s;
this.a = a;
this.b = b;
start(); // el Thread se autoarranca
}
public void run()
{
try
{
<c�digo de servicio>
}
catch(InterruptedException e)
{}
}
}
Obs�rvese que run acceder�a a las variables miembro directamente de modo equivalente que la funci�n servicio en que estos datos llegan como par�metros.
El m�todo start es al comando java (� jview) lo que run es a main
La llamada a una funci�n en
modo cl�sico se puede ver como un caso de particular en el modelo multithreaded.
Basta con indicar que el Thread del programa "llamante" se bloquee hasta que el
"llamdado" no termine. Ello se consigue utilizando el m�todo join:
...
new
Servicio("Hola", 5, true).join();
...
El m�todo join es utilizado en aquellos casos en que se lanzan varios threads y no se quiere continuar hasta que acaben todos ellos:
Thread t1 = new ...
Thread t2 =
new ...
Thread t3 = new
...
t1.join();
t2.join();
t3.join();
En este caso hasta que no
terminen los tres Threads t1, t2 y t3 el programa no pasar� la zona de joins. En
cierto modo act�a como un elemento transaccional (se componen en l�gica
"AND").
4.- Herencia de Thread versus
implementaci�n de Runnable
class
EjemploThread
{
public
static void main(String args[])
{
// Utilizando herencia de
Thread
PingPong t1=
new PingPong(1000,"Ping");
PingPong t2= new
PingPong(3000,"Pong");
t1.start();
t2.start();
// Implementando Runnable
PingPongr t1r=
new PingPongr(1000,"Pingr");
PingPongr t2r= new PingPongr(3000,"Pongr");
t1r.t.start();
t2r.t.start();
}
}
//
// PingPong.java
//
class PingPong
extends Thread
{
int interval;
String text;
PingPong(int
interval0, String text0)
{
interval = interval0;
text = text0;
}
public void
run()
{
try
{
for(;;)
{
System.out.println(text);
sleep(interval);
}
}
catch
( InterruptedException e )
{
return;
}
}
}
//
// PingPongr.java
//
class PingPongr
implements Runnable
{
// Hay que crear el
Thread
Thread t;
int Interval;
String
text;
PingPongr(int
Interval0,String text0)
{
// Aqui asociamos el Thread al
Objeto
t=new Thread(this);
Interval =
Interval0;
text=text0;
}
public void
run()
{
try
{
for(;;)
{
System.out.println(text);
// El
thread es t no la propia clase
t.sleep(Interval);
}
}
catch ( InterruptedException
e)
{
return;
}
}
}
5.- Ciclo de vida de un
Thread.
...
Thread.currentThread().sleep(2000);
// el programa se detiene durante 2
segundos
...
6. Sincronizaci�n
7.- Ejemplo
/// Recurso accedido por p y c
class Q
{
int n;
boolean valueSet = false;
synchronized
int get()
{
if (!valueSet)
try
{wait();} catch (InterruptedException e){}
System.out.println("Obtenido:
" + n);
valueSet =
false;
notify();
return
n;
}
synchronized
void put(int n)
{
if (valueSet)
try
{wait();} catch (InterruptedException e){}
this.n = n;
valueSet = true;
System.out.println("Colocado:
" + n); notify();
}
}
Productor implements
Runnable
{
Q q;
Thread t;
Productor(Q
q)
{
this.q = q; t = new
Thread(this, "Productor");
t.start();
}
public void
run()
{
int i = 0;
while(true)
{
try
{t.sleep(1500);} catch(Exception e){}
q.put(i++);
}
}
}
Consumidor implements
Runnable
{
Q q;
Thread t;
Consumidor(Q
q)
{
this.q = q; t = new
Thread(this, "Consumidor");
t.start();
}
public void
run()
{
while(true)
{
try
{t.sleep(1000);} catch(Exception e){}
q.get();
}
}
}
PC
{
public static void main(String args[])
{
Q q = new Q();
new Productor(q);
new Consumidor(q);
}
}
8.- Miscel�nea
Unidad anterior - Unidad siguiente
Copyright DENVIR STUDIOS �
Lima - Per�, 2002