Publicado el 14 de Enero del 2017
1.022 visualizaciones desde el 14 de Enero del 2017
507,9 KB
30 paginas
Creado hace 15a (12/10/2009)
PROGRAMACION CONCURRENTE Y
DISTRIBUIDA
III.1 Concurrencia con Java: Thread Java
J.M. Drake
L. Barros
Notas:
1
Concurrencia en Java.
Java posibilita la programación concurrente a través de
threads.
Los threads son procesos ligeros, con línea de flujo de control
propia pero que comparte el espacio de direcciones del
programa.
Los threads hacen posible la ejecución concurrente de código.
Los cambios de contexto son menos costosos en tiempo de ejecución.
Notas:
Procodis’09: III.1- Thread Java José M.Drake
2
Java es un lenguaje que permite formular programas concurrentes. Esto es, existen en Java
sentencias que permiten construir un programa con múltiples líneas 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 básica 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 protección 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 capítulos previos del curso la concurrencia proporciona muchas ventajas
de programación, tanto en la gestión de entradas y salidas, de dispositivos externos o de las
interacciones con el usuario, como para hacer que la estructura del programa sea mas próxima al
dominio del problema al facilitar la programación orientada a objetos y con objetos activos.
En contrapartida la programación concurrente requiere abordar nuevos situaciones sobre
sincronización 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.
2
Class Thread
Un thread se crea en Java instanciando un objeto de la clase
Thread.
El código que ejecuta un thread está definido por el método
run() que tiene todo objeto que sea instancia de la clases Thread.
La ejecución del thread se inicia cuando sobre el objeto Thread
se ejecuta el método start().
De forma natural, un thread termina cuando en run() se alcanza
una sentencia return o el final del método. (Existen otras formas
de terminación forzada)
Procodis’09: III.1- Thread Java José M.Drake
3
Notas:
Para declarar un thread en un programa Java se debe instanciar un objeto que sea una extensión
(extends) la clase “java.lang.Thread”. Por cada objeto de con estas características que se declare en
un programa java, se crea un nuevo thread con una línea de flujo de control propia que se ejecutará
concurrentemente con el programa principal y con los restantes threads.
El código que ejecuta un thread es el expresado através de su método 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 método run() original con un código que establezca la actividad deseada.
La ejecución del thread creado con la instanciación de un objeto derivado de Threads comienza
cuando se invoca en el programa principal (o en otro thread activo) el método start del objeto.
Existen muchas formas de concluir un threads. La natural es cuando en el método run() que define
su actividad, se alcanza alguna sentencia end. Más adelante se analizarán otros métodos heredados
de Thread que permiten abortar o elevar excepciones en el thread, y que pueden conducir a su
finalización.
3
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)
Procodis’09: III.1- Thread Java José M.Drake
4
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 básicas:
- Las que requieren que el código del método run() se especifique explícitamente en la declaración
de la clase.
Por ejemplo:
Thread(String threadName)
- Las que requieren un parámetro de inicializanción 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 verificación
cada thread pueda autoidentificarse, o de si se le crea dentro de un ThreadGroup, lo cual limita su
accesibilidad y su capacidad de interacción con threads que han sido creados en otros ThreadGroup.
4
Creación de un thread por herencia.
public class PingPong extends Thread{
private String word; // Lo que va a escribir.
private int delay;
public PingPong(String queDecir,int cadaCuantosMs){
// Tiempo entre escrituras
word = queDecir; delay = cadaCuantosMs; };
public void run(){ //Se sobrescribe run() de Thread
while(true){
System.out.print(word + “ “);
try{
sleep(delay);
public static void main(String[] args){
// Declaración de 2 threads
PingPong t1 =new PingPong(“PING”,33);
PingPong t2= new PingPong(“PONG”,10);
// Activación
t1.start();
t2.start();
// Espera 2 segundos
try{ sleep(5000);
}catch (InterruptedException e){};
} catch(InterruptedException e){ return; }
// Finaliza la ejecución de los threads
}
}
}
t1.stop();
t2.stop();
}
}
Notas:
Procodis’09: III.1- Thread Java José M.Drake
5
La clase java PingPong es una extensión 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 código 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 método sleep puede elevar una excepción
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 creación supone que a los thread se les ha dotado de los recursos que
requieren, pero aun están inactivos (esto es no se está ejecutando las sentencias de su método run()).
Con las sentencias que invocan los métodos t1.start() y t2.start() de los objetos de la clase
PingPong, se inicia en la ejecución del código 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 métodos run()). Se acabarán desde el entorno abortando el programa principal y
todo lo que depende de él.
5
Interface Runnable
Definición de la interface Runnable:
public interface Runnable {
public abstract void run();
}
Thread
Clase activa
+ run()
Creación de un thread a partir de la interface Runnable:
1) public class MiClase implements Runnable{
public void run(){ ......}
}
2) .....
MiClase ot = new MiClase();
Thread t1 = new Thread(ot);
t1.start();
.....
Procodis’09: III.1- Thread Java José M.Drake
Notas:
<<interface>>
Runnable
+ run()
Clase raíz dominio
Thread
Clase activa
+ run()
6
La segunda posibilidad de crear un thread es a través de la utilización de un objeto que
implemente la interface Runnable, y con el que se incorpora el método 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
código del método abstracto run() al que obliga ser la implementación 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 parámetro de su constructor.
Este es el procedimiento mas habitual de crear threads en java, ya que permite herencia múltiple,
al poder ser la clase Runnable extensión de cualquier otra clase que ya esté definida.
6
Creación de Thread a través de la interfaz
Runnable.
public class PingPong implements Runnable {
private String word; // Lo que va a escribir.
private int delay;
public PingPong(String queDecir, int cadaCuantosMs){
// Tiempo entre escrituras
word = queDecir; delay = cadaCuantosMs; };
public void run(){
while(true){
System.out.print(word + “ “);
try{ sleep(delay);
}catch(InterruptedException e){return;}
public class PruebaRunnable{
public static void main(String[] args){
// Los objetos r1 y r2 definen la funcionalidad.
// (definen los métodos run())
PingPong r1 =new PingPong(“PING”,33);
PingPong r2= new PingPong(“PONG”,10);
// Se crean los threads
Thread t1 = new Thread(r1);
Thread t2= new Thread(r2);
// Se activan los threads
t1.start();
t2.start();
}
}
}
}
}
Notas:
Procodis’09: III.1- Thread Java José M.Drake
7
La clase PingPong implementa la interfaz Runnable, y en consecuencia define el método run() que
constituirá el cuerpo de futuros threads.
Aun que no ocurre en el ejemplo, la clase PingPong podría ser una extensión de otra clase, de la
que heredaría su funcionalidad y sus recursos.
Cuando instancian los threads t1 y t2 (en este caso directamente de la clase Thread, aunque podría
ser de cualquier otra derivada de ella), se le pasa como valor actual del parámetro Runnable
thre
Comentarios de: PROGRAMACION CONCURRENTE Y DISTRIBUIDA - III.1 Concurrencia con Java: Thread Java (0)
No hay comentarios