100% encontró este documento útil (1 voto)
106 vistas

3.1-Concurrencia Con Java Thread Java

Este documento describe la programación concurrente con hilos en Java. Java permite la creación de hilos (threads) que permiten la ejecución concurrente de código. Los hilos son ligeros y comparten el mismo espacio de memoria. Pueden crearse hilos extendiendo la clase Thread o implementando la interfaz Runnable. El código que ejecuta cada hilo está definido en el método run().

Cargado por

Aly Laly
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
100% encontró este documento útil (1 voto)
106 vistas

3.1-Concurrencia Con Java Thread Java

Este documento describe la programación concurrente con hilos en Java. Java permite la creación de hilos (threads) que permiten la ejecución concurrente de código. Los hilos son ligeros y comparten el mismo espacio de memoria. Pueden crearse hilos extendiendo la clase Thread o implementando la interfaz Runnable. El código que ejecuta cada hilo está definido en el método run().

Cargado por

Aly Laly
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 30

PROGRAMACION CONCURRENTE Y

DISTRIBUIDA

III.1 Concurrencia con Java: Thread Java

J.M. Drake
L. Barros

Notas:

Concurrencia en Java.
Java posibilita la programacin concurrente a travs de
threads.
Los threads son procesos ligeros, con lnea de flujo de control
propia pero que comparte el espacio de direcciones del
programa.
Los threads hacen posible la ejecucin concurrente de cdigo.
Los cambios de contexto son menos costosos en tiempo de ejecucin.

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

Java es un lenguaje que permite formular programas concurrentes. Esto es, existen en Java
sentencias que permiten construir un programa con mltiples lneas de flujo de control ( threads) que
se ejecutan concurrentemente si la plataforma es multiprocesadora o que ejecutan de forma
entralazada sus sentencias dando apariencia de concurrencia si la plataforma es monoprocesadora.
La unidad bsica de concurrencia en Java es el Thread, que representa un proceso ligero que
comparte el mismo espacio de variables con los restantes threads del mismo programa. Dado que los
Threads de un programa Java son todos ellos internos al programa, no se necesita la proteccin de
seguridad de disponer de un nico espacio de variables propio de cada threads, y al tener un espacio
de memoria nico se aligera y facilita los cambios de contexto entre threads.
Como se ha visto en los captulos previos del curso la concurrencia proporciona muchas ventajas
de programacin, tanto en la gestin de entradas y salidas, de dispositivos externos o de las
interacciones con el usuario, como para hacer que la estructura del programa sea mas prxima al
dominio del problema al facilitar la programacin orientada a objetos y con objetos activos.
En contrapartida la programacin concurrente requiere abordar nuevos situaciones sobre
sincronizacin entre threads y acceso de forma segura a los objetos compartidos, por lo que el
lenguaje Java debe proporcionar sentencias y recursos que permitan abordarlas.

Class Thread
Un thread se crea en Java instanciando un objeto de la clase
Thread.
El cdigo que ejecuta un thread est definido por el mtodo
run() que tiene todo objeto que sea instancia de la clases Thread.
La ejecucin del thread se inicia cuando sobre el objeto Thread
se ejecuta el mtodo start().
De forma natural, un thread termina cuando en run() se alcanza
una sentencia return o el final del mtodo. (Existen otras formas
de terminacin forzada)
Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

Para declarar un thread en un programa Java se debe instanciar un objeto que sea una extensin
(extends) la clase java.lang.Thread. Por cada objeto de con estas caractersticas que se declare en
un programa java, se crea un nuevo thread con una lnea de flujo de control propia que se ejecutar
concurrentemente con el programa principal y con los restantes threads.
El cdigo que ejecuta un thread es el expresado atravs de su mtodo run(), que es heredado de la
clase Thread. A fin de definir la actividad que se quiere que ejecute el nuevo thread es necesario
sobreescribir el mtodo run() original con un cdigo que establezca la actividad deseada.
La ejecucin del thread creado con la instanciacin de un objeto derivado de Threads comienza
cuando se invoca en el programa principal (o en otro thread activo) el mtodo start del objeto.
Existen muchas formas de concluir un threads. La natural es cuando en el mtodo run() que define
su actividad, se alcanza alguna sentencia end. Ms adelante se analizarn otros mtodos heredados
de Thread que permiten abortar o elevar excepciones en el thread, y que pueden conducir a su
finalizacin.

Constructores de la clase Thread.


Thread()
Thread(Runnable threadOb)
Thread(Runnable threadOb, String threadName)
Thread(String threadName)
Thread(ThreadGroup groupOb, Runnable threadOb)
Thread(ThreadGroup groupOb, Runnable threadOb,
String threadName);
Thread(ThreadGroup groupOb, String threadName)

Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

Existen varios constructores de la clase Thread (y transferido por herencia a todas su extensiones).
Desde el punto de vista estructural existen dos variantes bsicas:
- Las que requieren que el cdigo del mtodo run() se especifique explcitamente en la declaracin
de la clase.
Por ejemplo:

Thread(String threadName)

- Las que requieren un parmetro de inicializancin que implemente la interfaz Runnable.


Por ejemplo:

Thread(Runnable threadOb)

Los restantes constructores resultan de si se asigna un nombre la threads, y que solo afecta para
inicializar ese atributo en la instancia del objeto, y pueda utilizarse para que en fases de verificacin
cada thread pueda autoidentificarse, o de si se le crea dentro de un ThreadGroup, lo cual limita su
accesibilidad y su capacidad de interaccin con threads que han sido creados en otros ThreadGroup.

Creacin de un thread por herencia.


public class PingPong extends Thread{
private String word;

// Lo que va a escribir.

private int delay;

// Tiempo entre escrituras

public static void main(String[] args){


// Declaracin de 2 threads
PingPong t1 =new PingPong(PING,33);

public PingPong(String queDecir,int cadaCuantosMs){

PingPong t2= new PingPong(PONG,10);

word = queDecir; delay = cadaCuantosMs; };

// Activacin

public void run(){ //Se sobrescribe run() de Thread

t1.start();

while(true){

t2.start();

System.out.print(word + );

// Espera 2 segundos

try{

try{ sleep(5000);

sleep(delay);

}catch (InterruptedException e){};

} catch(InterruptedException e){ return; }

// Finaliza la ejecucin de los threads

t1.stop();

t2.stop();

}
}

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

La clase java PingPong es una extensin de la clase Threads, por lo que cada una de sus instancias
(por ejemplo t1 y t2 representan un nuevo thread java.
El metodo run() es sobreescrito en la clase PingPong, y establece el cdigo que se ejecutar en
cada instancia de la clase. En el ejemplo consiste en un bucle indefinido de escribir el valor del
atributo word, y de suspenderse durante los milisegundos expresador en el atributo delay.
La sentencia try .. catch tiene que ser utilizada porque el mtodo sleep puede elevar una excepcin
del tipo InterruptException.
Con las sentencias que declaran e instancian los dos objetos t1 y t2 de la clase PingPong se han
creado dos threads. La creacin supone que a los thread se les ha dotado de los recursos que
requieren, pero aun estn inactivos (esto es no se est ejecutando las sentencias de su mtodo run()).
Con las sentencias que invocan los mtodos t1.start() y t2.start() de los objetos de la clase
PingPong, se inicia en la ejecucin del cdigo de los respectivos procedimiento run().
En este caso (para hacer el ejemplo sencillo) los threads no finalizan nunca (observese el bucle
while(true) de los mtodos run()). Se acabarn desde el entorno abortando el programa principal y
todo lo que depende de l.

Interface Runnable
Definicin de la interface Runnable:

Thread

public interface Runnable {


public abstract void run();
}

Clase activa
+ run()

Creacin de un thread a partir de la interface Runnable:


1) public class MiClase implements Runnable{
public void run(){ ......}
}
<<interface>>

Runnable
+ run()

2) .....
MiClase ot = new MiClase();
Thread t1 = new Thread(ot);
t1.start();
.....
Notas:

Procodis09: III.1- Thread Java

Thread

Clase raz dominio

Clase activa
+ run()

Jos M.Drake

La segunda posibilidad de crear un thread es a travs de la utilizacin de un objeto que


implemente la interface Runnable, y con el que se incorpora el mtodo run() que establece las
actividades que va a realizar.
La clase MiClase implementa la interfaz Runnable, y por ello se le requiere que establezca el
cdigo del mtodo abstracto run() al que obliga ser la implementacin de la interfaz Runnable.
En el programa que declara el nuevo thread, se debe declarar primero el objeto t1 de la clase
MiClase, y posteriormente cuando se crea el threads (se instancia el objeto t1 de la clase Thread) se
le pasa como parmetro de su constructor.
Este es el procedimiento mas habitual de crear threads en java, ya que permite herencia mltiple,
al poder ser la clase Runnable extensin de cualquier otra clase que ya est definida.

Creacin de Thread a travs de la interfaz


Runnable.
public class PingPong implements Runnable {
private String word;
private int delay;

public class PruebaRunnable{

// Lo que va a escribir.

public static void main(String[] args){

// Tiempo entre escrituras

// Los objetos r1 y r2 definen la funcionalidad.

public PingPong(String queDecir, int cadaCuantosMs){

// (definen los mtodos run())

word = queDecir; delay = cadaCuantosMs; };

PingPong r1 =new PingPong(PING,33);


PingPong r2= new PingPong(PONG,10);

public void run(){

// Se crean los threads

while(true){

Thread t1 = new Thread(r1);

System.out.print(word + );

Thread t2= new Thread(r2);

try{ sleep(delay);

// Se activan los threads

}catch(InterruptedException e){return;}

t1.start();

t2.start();

}
}

Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

La clase PingPong implementa la interfaz Runnable, y en consecuencia define el mtodo run() que
constituir el cuerpo de futuros threads.
Aun que no ocurre en el ejemplo, la clase PingPong podra ser una extensin de otra clase, de la
que heredara su funcionalidad y sus recursos.
Cuando instancian los threads t1 y t2 (en este caso directamente de la clase Thread, aunque podra
ser de cualquier otra derivada de ella), se le pasa como valor actual del parmetro Runnable
threadOb del constructor, los objetos Runnables r1 y r2 de la clase PingPong que fueron previamente
instanciados.
La declaracin de los objetos runnables podra ser directa dentro de la declaracin de los threads,
solo que en ese caso seran annimos:
PingPong t1 = new Thread(new PingPong(ping,33));
PingPong t2 = new Thread(new PingPong(PONG,100));
O incluso con los thread tambin annimos:
new Thread(new PingPong(ping,33));
new Thread(new PingPong(PONG,100));

Delegacin en una operacin costosa en un thread


public class threadAgente{
....
public void operacionCostosa(){
....
};
static public void main(String[] args}{
....
// Lanza la ejecucin costosa en un thread annimo concurrente
new Thread(
new Runnable(){
public void run(){ operacionCostosa();}
}
).start();
//main ejecuta concurrentemente otra tarea de inters
....
};
}
Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

Clase activa con thread auto lanzado


public class SelfRun implements Runnable{
private Thread internalThread;
private boolean noStopRequired;
public SelfRun(){
System.out.println("Comienza ejecucin");
noStopRequired=true;
internalThread=new Thread(this);
internalThread.start(); }
public void run(){
while(noStopRequired){
System.out.println("En ejecucin");
try{ Thread.sleep(500);
}catch (InterruptedException e){
Thread.currentThread().interrupt();}
}
}
public void stopRequest(){
noStopRequired=false;
internalThread.interrupt();}

public static void main(String[] args) {


SelfRun objActivo=new SelfRun();
// Espera durante 2 segundos
try{Thread.sleep(2000);
}catch(InterruptedException e){};
// Termina el objeto activo
System.out.println("main invoca stopRequest()");
objActivo.stopRequest();
}
}

Respuesta del programa:


Comienza ejecucin
En ejecucin
En ejecucin
En ejecucin
En ejecucin
En ejecucin
main invoca stopRequest()

Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

Mtodos de la clase Thread: Inicio y finalizacin.


void run()
Contiene el cdigo que ejecuta el thread.

void start()
Inicia la ejecucin del thread.

void stop()
Termina la ejecucin del thread (*)

static Thread currentThread()


Retorna el objeto Thread que ha ejecutado este mtodo.

final void sleep(long milliseconds) throws InterruptedException


Suspende la ejecucin del thread por el nmero de milisegundos
especificados.
Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

El mtodo stop() es muy inseguro. Si se destruye un thread con recursos tomados estos
permanecen tomados y no accesibles a otros componentes de la aplicacin. Es un mtodo ya
obsoleto que ser eliminado en las prximas versiones. Un thread debe terminarse utilizando el
mtodo interrupt().
El mtodo sleep puede lanzar la excepcin InterruptedException (lo que ocurre si mientras que el
thread est suspendido, otro threads ejecuta el mtodo Interrupt de l). Por esta razn, el mtodo
sleep debe ejecutarse siempre dentro de una sentencia try .. catch:
try{
....
sleep(500);
....
}
catch (InterruptedException e {...};

10

10

Ejemplo de uso del mtodo currentThread().


public class Cliente extends Thread{

public static void main(String[]


args){
Cliente juan= new Cliente();
juan.setName(Juan Lpez");
Cliente ines= new Cliente();
ines.setName(Ins Garca");
juan.start();
ines.start();
}

public void run(){


Recurso.uso();
try {
Thread.sleep(2000);
} catch(InterruptedException e){};
};
}

public class Recurso{


static synchronized void uso(){
Thread t = Thread.currentThread();
System.out.println(Soy +t.getName());
}
}
Notas: Procodis09: III.1- Thread Java

Jos M.Drake

En el ejemplo se instancian varios threads (juan e ines) del tipo Cliente que es una extensin de la
clase Thread.
En la definicin de su actividad (mtodo run()), invocan el mtodo uso de un objeto construido
con la clase esttica Recurso.
Dentro del objeto Recurso cada thread se autoidentifica a travs del mtodo currentThread,( y en
este caso imprime su identificador por defecto: nombre,prioridad, Grupos, etc.). Con ello, se puede
escribir en un recurso compartido por muchos threads sentencias que se particularicen en funcin de
que thread lo est visitando.
El nombre de los thread se establece a travs del mtodo setName, se podra haber hecho de forma
equivalente a travs del contructor:
Cliente juan = new Cliente(Juan Lpez);
Cliente ines = new Cliente(Ines Garca);

11

11

Estados de un thread
Alive
Suspended

Waiting

suspend()
wait()

resume()

notify()

interrupt()

interrupt()

UnStarted

start()

stop()

Interrupted

Runnable

Dead

interrupted()
timeout

sleep()

interrupt()

Sleeping

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

Estado UnStarted: El thread ha sido instanciado pero no se arrancado su ejecucin.


Estado Alive: El cdigo del mtodo run() se est ejecutando.
Subestado Runnable: La ejecucin del thread esta siendo planificada por el procesador.
Subestado Interrupted: La ejecucin del thread est siendo planificada por el procesador,
pero ero se ha invocado el mtodo Interrupt sobre el thread.
Subestado Suspended: El thread est supendido indefinidamente (porque sobre l se ha
invocado el mtodo suspend(). El thread no est siendo planificado.
Subestado Sleeping: El thread est supendido temporalmente (durante el nmero de ms
establecido por el argumento del mtodo sleep() que lo ha dormido).
Subestado Waiting: El thread est supendido indefinidamente (sobre la variable de condicin
del objeto thread por haber invocado el mismo el mtodo wait()).
Estado Dead: El thread ha finalizado. Un thread finaliza por uno de los tres siguientes modos:
- El mtodo run() ejecuta la sentencia return o alcanza su final.
- Se invoca desde un thread activo el mtodo stop().
- No se recupera la excepcin InterruptedException estando en Waiting o Sleeping.

12

12

Mtodos de la clase Thread: Control de finalizacin.


final boolean isAlive()
z Retorna true si el thread se encuentra en el estado Alive (en alguno de sus
subestados), esto es, ya ha comenzado y aun no ha terminado.

final void join() throws InterruptedException


z Suspende el thread que invoca hasta que el thread invocado haya
terminado.

final void join(long milliseconds) throws InterruptedException


z Suspende el thread que invoca hasta que el thread invocado haya
terminado o hasta que hayan transcurrido los milisegundos.

Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

13

13

Ejemplo de uso del mtodo isAlive().


public class Obrera extends Thread{
private String resultado = "No calculado";

class Ejemplo_isAlive {
public static void main(String[] args){
Obrera agente =new Obrera();
agente.start();
// Hace algo durante el clculo.
......
//Espera que agente haya terminado
while (agente.isAlive()) Thread.yield();
// Utiliza el resultado.

public void run(){


resultado = calcula();
}
private String calcula(){
// Realiza un clculo largo.
try {Thread.sleep(10000);
} catch(InterruptedException e){};
return "Ya calculado";
}
public String getResultado(){
return resultado;
}

System.out.println(agente.getResultado());
}
}

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

El programa principal main instancia el thread agente de la clase Obrera (es un thread
porque es una extensin de Thread), y delega en l que para que invoque y ejecute Calcula().
Concurrentemente el programa main ejecuta alguna otra actividad. Cuando finaliza se introduce
en un lazo de espera activa en el que haciendo uso del mtodo isAlive espera a que la Obrera agente
haya concluido.
Luego lee de ella el resultado. Observese que aunque ha concluido se pueden acceder a su
variable resultado a travs del mtodo getResultado().
ESTE ES UN PROGRAMA MAL DISEADO PORQUE REQUIERE UNA ESPERA ACTIVA.

14

14

Ejemplo de uso del mtodo join()


public class Obrera extends Thread{
private String resultado = "No calculado";

class Ejemplo_join {
public static void main(String[] args){
Obrera agente = new Obrera();
agente.start();
// Hace algo durante el clculo.

public void run(){


resultado = Calcula();
}

try { //Espera a que agente termine


agente.join();
}catch (InterruptedException e){};
// Utiliza el resultado.

String Calcula(){
// Realiza un clculo largo.
try {Thread.sleep(10000);
}catch(InterruptedException e){};
return "Ya calculado";
}

System.out.println(agente.getResultado());
}

public String getResultado(){


return resultado;
}
}

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

Este programa tiene la misma funcionalidad que el programa de la pgina anterior (12).
Sin embargo este programa es mucho mas eficiente, esto es requerir menos tiempo de CPU para
ser ejecutado, ya que la espera ahora es suspendida (Waiting). El programa principal main invoca el
mtodo join sobre el thread Obrera agente. Main pasa a estado Waiting y espera suspendido all hasta
que tras la finalizacin del thread agente, lo retorna al estado Runnable.
La invocacin del mtodo join hay que invocarlo dentro de una sentencia try .. catch, ya que si
sobre main se invoca el mtodo interrupt, se elevara la excepcin InterruptedException.

15

15

Mtodos de la clase Thread: Interrupcin.


void interrupt()
El thread pasa a estado Interrupted. Si est en los estados Waiting,
Joining o Sleeping termina y lanza la excepcin InterruptedException.
Si est en estado Runnable, continua ejecutndose aunque cambia su
estado a Interrupted.

static boolean interrupted()


Procedimiento esttico. Retorna true si el thread que lo invoca se
encuentra en estado Interrupted. Si estuviese en el estado Interrupted
se pasa al estado Runnable.

boolean isInterrupted()
Retorna true si el objeto thread en que se invoca se encontrase en el
estado Interrupted. La ejecucin de este mtodo no cambia el estado
del thread.
Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

16

16

Uso del mtodo isInterrupted().


public class InterruptCheck {
public static void main(String[] args) {
Thread t=Thread.currentThread();
System.out.println("A:t.isInterrupted()="+ t.isInterrupted());
t.interrupt();
System.out.println("B:t.isInterrupted()="+ t.isInterrupted());
No cambia
System.out.println("C:t.isInterrupted()="+ t.isInterrupted());
try{
Respuesta del programa:
Thread.sleep(2000);
A:t.isInterrupted()=false
System.out.println("No ha sido interrumpida");
B:t.isInterrupted()=true
C:t.isInterrupted()=true
}catch(InterruptedException e){
No ha sido interrumpida
System.out.println("Si ha sido interrumpida");
D:t.isInterrupted()=false
}
System.out.println("D:t.isInterrupted()="+ t.isInterrupted());
}
Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

17

17

Uso del metodo esttico Thread.interrupted()


public class InterruptReset {
public static void main(String[] args) {
Thread t=Thread.currentThread();
System.out.println("A: Thread.interrupted()="+Thread.interrupted());
t.interrupt();
System.out.println("B: Thread.interrupted()="+Thread.interrupted());
cambia
System.out.println("C: Thread.interrupted()="+Thread.interrupted());
try{
Respuesta del programa:
Thread.sleep(2000);
A: Thread.interrupted()=false
System.out.println("No ha sido interrumpida");
B: Thread.interrupted()=true
}catch(InterruptedException e){
C: Thread.interrupted()=false
System.out.println("Si ha sido interrumpida");
No ha sido interrumpida
}
D: t.isInterrupted()=false
System.out.println("D: t.isInterrupted()="+t.isInterrupted());
}
}
Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

18

18

Ejemplo de finalizacin por InterruptedException.


public class MiThread extends Thread{

public class Ejemplo_Fin_por_Interrupt {

public void run(){


while (true) {
System.out.println("Ejecuto");
try{
Thread.sleep(100);
}catch (InterruptedException e){
System.out.println("Termino en sleep");
};
};
return;
}

public static void main(String[] args){


Thread elThread= new MiThread();
elThread.start();
try{
Thread.sleep(1000);
}catch (InterruptedException e){};
elThread.interrupt();
}
}

Procodis09: III.1- Thread Java

Jos M.Drake

19

Notas:

El thread elThread ejecuta un bucle peridico que escribe Ejecuto y luego se suspende durante
100 ms.
El programa principal main, espera durante un tiempo (1000 ms) y luego invoca el mtodo
interrupt() del thread elThread.
Cuando se invoca el mtodo interrupt() elTthread puede estar en uno de dos estados:
- Si est en el estado Runnable, pasa al estado Interrupted hasta que se invoque el
mtodo sleep() y pase al estado
Sleeping, instante en el que se eleva la excepcin InterruptedException en
elThread, y tras escribir el comentario finaliza
elThread.
- Si est en el estado Sleeping, se eleva de forma inmediata la excepcin
InterruptedException en elThread, y tras escribir
el comentario finaliza elThread.

19

Ejemplo de uso de interrupt() e interrupted()


public class MiThread extends Thread{

public class Ejemplo_Fin_por_Interrupt {

public void run(){


while (!Thread.interrupted()) {
System.out.println("Ejecuto");
};
System.out.println(Termino");
return;
}

public static void main(String[] args){


Thread elThread= new MiThread();
elThread.start();
try{
Thread.sleep(1000);
}catch (InterruptedException e){};
elThread.interrupt();
}

}
}

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

En este caso, elThread permanece permanentemente es el estado Runnable, ejecutando la escritura


del texto Ejecuto en un bucle indefinido que perdura mientas que el resultado de invocar
interrupted() sea false.
Cuando tras 1000 ms main invoque el mtodo interrupted() sobre elThread, este pasa a estado
Interrupted, y en la siguiente ejecucin de la sentencia while sale del bucle, y tras escribir el texto de
salida, ejecuta return y concluye.

20

20

Interrupcin durante sleep


public class SleepInterrupt implements Runnable {
public void run(){
try{
System.out.println("in run(): me duermo 20 s");
Thread.sleep(20000);
System.out.println("in run(): me despierto");
}catch (InterruptedException e){
System.out.println(
"in run(): interrumpida en sleep");
return;
}
System.out.println("in run(): fin normal");
}
....

...
public static void main(String[] args) {
SleepInterrupt si=new SleepInterrupt();
Thread t=new Thread(si);
t.start();
try{
Thread.sleep(1000);
}catch (InterruptedException e){};
System.out.println("in main(): Intterupo a t");
t.interrupt();
System.out.println("in main(): termina");
}
}

Respuesta del programa:


in run(): me duermo 20 s
in main(): Intterupo a t
in run(): interrumpida en sleep
in main(): termina
Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

21

21

Interrupcin pendiente y sleep()


public class PendingInterrupt {
public static void main(String[] args) {
if (args.length>0){ Thread.currentThread().interrupt();}
long tiempoInicial=System.currentTimeMillis();
try{
Thread.sleep(2000);
System.out.println("No es interrumpida");
}catch (InterruptedException e){
System.out.println("Es interrumpida");
}
System.out.println("Tiempo gastado: "+
(System.currentTimeMillis()-tiempoInicial));
}
}

Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

22

Respuesta a java PendingInterrupt:


No es interrumpida
Tiempo gastado: 2000

Respuesta a java PendingInterrupt yes:


Es interrumpida
Tiempo gastado: 0

22

Mtodos suspend() y resume() de la clase Thread.


El mtodo suspend() permiten parar reversiblemente la
ejecucin de un Thread. Se reanuda cuando sobre l se ejecute
el mtodo resume().
Ejecutar suspend sobre un thread suspendido o ejecutar
resume() sobre un thread no suspendido no tiene ningn
efecto.
public final void suspend()
z Suspende la ejecucin del thread. Los objetos sobre los que tena derecho
de acceso quedan cerrados para el acceso de otros threads hasta que tras
que le sea aplicado resume(), los libere.

public final void resume()


z Reanuda el thread si ya estuviera suspendido.

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

Los metodos suspend() y resume() ser eliminado en futuras versiones de java, al igual que el
mtodo stop() ya que son muy proclives a provocar bloqueos.

23

23

Ejemplo de aplicacin de mtodos suspend() y resume()


El procedimiento ConfirmaCancelacion() suspende la actividad del
thread que se pasa como el argumento elThread, mientras se confirma
su abandono definitivo.
public void ConfirmaCancelacion(Thread elThread) {
elThread.suspend();
if (DebeCancelarse(Realmente se cancela?))
elThread.interrupt();
else
elThread.resume();
}

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

El ejemplo consiste en el procedimiento ConfirmaCancelacion para confirmar la suspensin


definitiva de un thread que se pasa como el argumento elThread.
Inicialmente se invoca sobre l el mtodo suspend() para suspenderlo hasta que el operador haya
establecido su destino.
Posteriormente se del operador que confirme o cancele la suspencin. En el primer caso, se invoca
el mtodo interrupt() para provocar la cancelacin ordenada del thread, y en el segundo caso se
invoca el mtodo resume() para que contine desde donde se suspendi.

24

24

Mtodos de la clase Thread: Control de planificacin.


Constantes
MAX_PRIORITY
MIN_PRIORITY
NORM_PRIORITY

//Mxima prioridad asignable al thread.


//Mnima prioridad asignable al thread.
//Prioridad por defecto que se asigna.

Mtodos
final void setPriority(int priority)
z Establece la prioridad de Thread.

final int getPriority()


z Retorna la prioridad que tiene asignada el thread.

static void yield()


z Se invoca el planificador para que se ejecute el thread en espera que
corresponda.

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

La planificacin de los thread est pobremente establecida en java, ya que no es un lenguaje de


tiempo real, y la mayora de las Maquinas virtuales java no son sensibles a la prioridad de los
threads.
De acuerdo con la especificacin original la planificacin debera realizarse con una poltica
expulsora (pre-emptive) y basada en prioridades.
Cada clase especializada de Thread, ofrece tres atributos constantes que pueden ser ledos y que
expresan los lmites de prioridades (MAX_PRIORITY,MIN_PRIORITY) que pueden asignarse a
cada thread de la clase, y el valor de prioridad por defecto (NORM_PRIORITY).
La norma de planificacin establece que el planificador nunca planifica un thread de entre los que
se encuentran en el estado Runnable o Interrupted si hay otro thread en los citados estados con mayor
prioridad asignada que l.

25

25

Manejo de prioridades
public class SimplePriorities extends Thread {
private int countDown = 5;
private volatile double d = 0; // No optimization
public SimplePriorities(int priority) {
setPriority(priority);
start();
}
public String toString() {
return super.toString() + ": " + countDown;
}
public void run() {
while(true) {
// An expensive, interruptable operation:
for(int i = 1; i < 100000; i++)
d = d + (Math.PI + Math.E) / (double)i;
System.out.println(this);
synchronized(this){
if(--countDown == 0) return;
}
}
}

public static void main(String[] args) {


new SimplePriorities(Thread.MAX_PRIORITY);
for(int i = 0; i < 5; i++)
new SimplePriorities(Thread.MIN_PRIORITY);
}
}

Procodis09: III.1- Thread Java

Jos M.Drake

Notas:

26

26

Mtodos de la clase Thread: Debuging y control.


String toString()
z Retorna un string con el nombre, prioridad y nombre del grupo del
Thread.

final String getName()


z Retorna el nombre del Thread

final void setName(String threadName)


z Establece el nombre del Thread.

static int activeCount()


z Retorna el nmero de threads activos en el grupo al que pertenece el
thread que invoca.

final ThreadGroup getThreadGroup()


z Retorna el grupo al que pertenece el thread que invoca.

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

Son mtodos que se utilizan habitualmente en las fase de validacin de los programas.

27

27

Mtodos de la clase Thread: Daemon.


Existen dos tipos de thread user y daemon . Su diferencia radica en su
efecto sobre la finalizacin de la aplicacin a la que pertenecen.
Una aplicacin termina solo si han terminado todos los threads de tipo user.
Cuando todos los threads de tipos user han terminado los thread de tipo
Daemon son terminados con independencia de cual sea su estado y la
aplicacin es finalizada.

Metodos relativos al tipo de Thread.


final void setDaemon(boolean state)
z Convierte un thread en daemon. Solo es aplicable despus de haber creado
el thread y antes de que se haya arrancado (start).

final boolean isDaemon()


z Retorna true si el thread es de tipo daemon.

Notas:

Procodis09: III.1- Thread Java

Jos M.Drake

28

28

Ejemplo de thread Daemond


public class DaemondThread implements Runnable{
public void run(){
System.out.println(Comienza run());
try{
while (true){
try{Thread.sleep(500);
}catch (InterruptedException e){};
System.out.println(run() ha despertado);
}
}finally{
System.out.println(Termina run());
}
}

Procodis09: III.1- Thread Java

public static void main(String[] args){


System.out.println(Comienza main());
Thread t=new Thread(new DaemondThread());
t.setDaemon(true);
t.start();
try{Thread.sleep(2000);
}catch (InterruptedException e){};
System.out.println(Termina main());
}
}

Respuesta de la ejecucin de main()


Comienza main()
Comienza run()
run() ha despertado
run() ha despertado
run() ha despertado
run() ha despertado
Termina main()
run() ha despertado
Jos M.Drake

29

Notas:
Los thread que han sido cualificado como daemon terminan de una forma diferente. Cuando la VM
detecta que slo permanecen en ejecucin thread Daemon termina su ejecucin.
Los daemon thread son utilizados para ejecutar tareas auxiliares de otros thread normales, cuando
estos han terminado aquellos no tienen funcin y finalizan.
En el ejemplo es interesante comprobar que cuando finaliza main, y la VM descuble que slo queda
el thread t , este finaliza de forma abrupta y no sale normalmente por la rama finally.

29

Ejemplo de thread User


public class DaemondThread implements Runnable{
public void run(){
System.out.println(Comienza run());
try{
while (true){
try{Thread.sleep(500);
}catch (InteruptedException e){};
System.out.println(run() ha despertado);
}
}finally{
System.out.println(Termina run());
}
}

Procodis09: III.1- Thread Java

public static void main(String[] args){


System.out.println(Comienza main());
Thread t=new Thread(new DaemonThread());
t.setDaemon(true);
t.start();
try{Thread.sleep(2000);
}catch (InterruptedException e){};
System.out.println(Termina main());
}
}
Respuesta de la ejecucin de main()
Comienza main()
Comienza run()
run() ha despertado
run() ha despertado
run() ha despertado
run() ha despertado
Termina main()
run() ha despertado
run() ha despertado
....

Jos M.Drake

30

Notas:
Los thread que han sido cualificado como daemon terminan de una forma diferente. Cuando la VM
detecta que slo permanecen en ejecucin thread Daemon termina su ejecucin.
Los daemon thread son utilizados para ejecutar tareas auxiliares de otros thread normales, cuando
estos han terminado aquellos no tienen funcin y finalizan.
En el ejemplo es interesante comprobar que cuando finaliza main, y la VM descuble que slo queda
el thread t , este finaliza de forma abrupta y no sale normalmente por la rama finally.

30

También podría gustarte