Logo Studenta

Tema 13 Clase 13 - Runnable

¡Este material tiene más páginas!

Vista previa del material en texto

CLASE 13
MODELO DE DESARROLLO DE PROGRAMAS Y PROGRAMACION 
CONCURRENTE
FAC.DE INGENIERIA - UNJu
INTERFAZ RUNNABLE
IMPLEMENTACIÓN DE HILOS USANDO LA INTERFAZ RUNNABLE
1 interfaz solamente puede contener métodos abstractos y/o variables estáticas y finales (constantes). 
Las clases pueden implementar métodos y contener variables q no sean constantes. 
1 interfaz no puede implementar cualquier método. 
1 clase q implemente 1interfaz debe implementar todos los métodos definidos en esa interfaz. 
1 interfaz tiene la posibilidad de poder extenderse de otras interfaces y, al contrario que las clases, 
puede extenderse de múltiples interfaces. 1 interfaz no puede ser instanciada con el operador new.
Es la técnica+adecuada p/la creación de aplicac.multitarea en lugar de la extens.de la clase Thread. 
Acciones:
o Implementar el método run() de la interfaz Runnable.
o Creación y ejecución de tareas.
Florencia
Resaltado
Florencia
Resaltado
Florencia
Resaltado
IMPLEMENTACIÓN DE HILOS USANDO LA INTERFAZ RUNNABLE
La interfaz Runnable debe ser implementada x cualquier clase cuyas instancias sean ejecutadas x 1 hilo. 
Dicha clase debe implementar el método run().
La implementación de la interfaz Runnable es la forma + habitual de crear tareas, ya q proporciona al 
desarrollador 1forma p/agrupar el trabajo de infraestructura de la clase. La interfaz establece el trabajo 
a realizar y la clase o clases q la implementan, indican cómo realizar ese trabajo, se puede construir 
1hilo sobre cualquier objeto q implemente la interfaz Runnable.
P/implementar esta interfaz, 1clase solo tiene q implementar el método run(). Dentro del run() se define 
el código q constituye el nuevo hilo. Después de haberse creado 1clase q implemente la interfaz 
Runnable se requiere crear un objeto del tipo Thread dentro de esa clase, usando cualquiera de los 
constructores de Thread.
Florencia
Resaltado
Florencia
Resaltado
Florencia
Resaltado
Florencia
Resaltado
IMPLEMENT.DE HILOS USANDO LA INTERFAZ RUNNABLE - ESQUEMA
// crear una clase con hilos
public class MiClase implements Runnable {
Thread unHilo;
MiClase() {
unHilo = new Thread();
}
public void run() {
if (unHilo != null) {
//cuerpo del hilo
}
}
}
La sig.forma gral.crea el hilo e inicia su 
ejecución en la clase q usa a MiClase:
MiClase miHilo = new MiClase ();
new Thread (miHilo).start();
IMPLEMENTACIÓN DEL MÉTODO RUN()
public class TareaRb implements Runnable
{public void run()
{for (int i=1; i<=100; i++)
{System.out.println("Nombre " + 
Thread.currentThread().getName());
try { Thread.sleep(100); }
catch (InterruptedException e) { 
e.printStackTrace(); } } } }
La interfaz Runnable incluye 1único método run(), q deba incluir las acciones a realizar x las tareas.
Al codificar este método mediante la implementación de la interfaz Runnable permite a la clase 
heredar al mismo tiempo la funcionalidad de alguna otra clase existente.
Código de 1clase p/la impresión de los nombres de los thread implementando la interfaz Runnable:
Al no heredar de Thread, no dispone de 1
constructor al q pasarle el nombre de la tarea; 
lo q se debe analizar es xq el método 
getName() devuelve el nombre de la tarea en 
ejecución. La respuesta es q la llamada a 
currentThread() no devuelve un objeto TareaRb
sino 1 objeto de la clase Thread q representa la 
tarea en ejecución.
CREACIÓN Y EJECUCIÓN DE TAREAS
public class Principal
{public static void main (String [] args)
//Se crea 1único objeto tarearb q se comparte en c/thread
{TareaRb t = new TareaRb();
// Las tareas son instancias de la clase Thread
Thread t1 = new Thread(t,"pepe");
Thread t2 = new Thread(t,"ana");
Thread t3 = new Thread(t,"juan");
// Los Threads se ponen en ejecución
t1.start();
t2.start();
t3.start(); } }
Toda tarea es 1thread o sea q habrá q crear 
tantos objetos de la clase Thread como 
tareas se quieran poner en ejecución, el 
tema es q el código asociado a esas tareas 
debe ser el q está definido en el método 
run() de la clase q implementa a Runnable().
P/crear objetos Thread con estas 
características, se debe usar alguno de los 
siguientes constructores de la clase Thread:
Thread(Runnable obj)
Thread (Runnable obj, String nombre)
En ambos casos, la creación y ejecución de 
las tareas en el ej.de la impresión de 
nombres quedaría :
EJEMPLOS SIN HILOS, CON THREAD Y CON INTERFAZ RUNNABLE
Se simula el proceso de cobro de un supermercado; donde:
• Los clientes adquieren productos
• 1cajera cobra los productos, pasándolos 1 a 1 x el escáner de la caja registradora. La cajera 
debe procesar la compra cliente a cliente, 1ro. le cobra al cliente 1, luego al cliente 2 y así 
sucesivamente. 
Se define 1 clase “Cajera” y una clase “Cliente” el cual tendrá un “array de enteros” q representa los 
productos q se compraron y el tiempo q la cajera tarda en pasar el producto x el escáner.
X ej. si se tiene 1 array con [1,3,5] significa q el cliente ha comprado 3 productos y q la cajera tarda en 
procesar al producto 1 ‘1 segundo’, al producto 2 ‘3 segundos’ y al producto 3 ‘5 segundos’, con lo cual 
se tarda en cobrar al cliente x toda su compra ‘9 segundos’.
CLASE “CAJERA.JAVA“
public class Cajera {
private String nombre;
public Cajera(String nombre) {
super();
this.nombre = nombre; }
public void procesarCompra (Cliente cliente, long timeStamp) {
System.out.println("La cajera " + this.nombre
+ " COMIENZA A PROCESAR LA COMPRA DEL CLIENTE "
+ cliente.getNombre() + " EN EL TIEMPO: "
+ (System.currentTimeMillis() - timeStamp) / 1000 + "seg");
for (int i = 0; i < cliente.getCarroCompra().length; i++) {
this.esperarXsegundos(cliente.getCarroCompra()[i]);
System.out.println("Procesado el producto " + (i + 1)
+ " ->Tiempo: " + (System.currentTimeMillis() - timeStamp) / 1000 + "seg"); }
System.out.println("La cajera " + this.nombre
+ " HA TERMINADO DE PROCESAR " + cliente.getNombre()
+ " EN EL TIEMPO: " + (System.currentTimeMillis() - timeStamp) / 1000 + "seg"); }
private void esperarXsegundos (int segundos) {
try { Thread.sleep(segundos * 1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt(); } } }
CLASE “CLIENTE.JAVA”
public class Cliente {
private String nombre;
private int[] carroCompra;
public Cliente(String nombre, int[] carroCompra) {
super();
this.nombre = nombre;
this.carroCompra = carroCompra;
}
public String getNombre() {
return nombre; }
public void setNombre(String nombre) {
this.nombre = nombre; }
public int[] getCarroCompra() {
return carroCompra; }
public void setCarroCompra(int[] carroCompra) {
this.carroCompra = carroCompra; } }
Si se ejecuta este programa con 2 Clientes y 
1solo proceso (q es lo q se suele hacer 
normalmente), se procesa 1ro.la compra del 
Cliente 1 y después la del Cliente 2, con lo 
cual se tarda el tiempo del Cliente 1 + 
Cliente 2. 
CUIDADO: Aunq se haya puesto 2 objetos de 
la clase Cajera (cajera1 y cajera2) no 
significa tener 2cajeras independientes, lo q 
se afirma es q dentro del mismo hilo se 
ejecutan 1ro.los métodos de la cajera1 y 
después los métodos de la cajera2. A nivel 
de procesamiento es como tener 1 sola 
cajera.
A continuación se implementa el método 
Main para lanzar el programa.
CLASE “MAIN.JAVA“
public class Main {
public static void main(String[] args) {
Cliente cliente1 = new Cliente("Cliente 1", new int[] { 2, 2, 1, 5, 2, 3 });
Cliente cliente2 = new Cliente("Cliente 2", new int[] { 1, 3, 5, 1, 1 });
Cajera cajera1 = new Cajera("Cajera 1");
Cajera cajera2 = new Cajera("Cajera 2");
// Tiempo inicial de referencia
long initialTime = System.currentTimeMillis();
cajera1.procesarCompra(cliente1, initialTime); 
cajera2.procesarCompra(cliente2, initialTime); } }
Si se ejecuta este ej.se observa cómo se procesa 1ro.la compra del cliente 1 y después la compra del 
cliente 2 tardando en procesar ambas compras un tiempo de 26 segundos.
CLASE “CAJERATHREAD.JAVA“
public classCajeraThread extends Thread {
private String nombre;
private Cliente cliente;
private long initialTime;
// Constructor, getter & setter
public CajeraThread(String nombre, Cliente cliente, long initialTime) {
super();
this.nombre = nombre;
this.cliente = cliente;
this.initialTime = initialTime;
}
Se pueden procesar 2clientes a la vez si hubiese 2cajeras y se asigna 1a c/cliente. P/ello se 
modifica la clase “Cajera.java” haciendo q herede de la clase Thread p/heredar y sobre-
escribiendo algunos de sus métodos. 1ro.se codifica la clase “CajeraThread.java” y después se 
explican sus características.
La clase 
“CajeraThread” 
hereda de la 
clase Thread
CLASE “CAJERATHREAD.JAVA“
@Override
public void run() {
System.out.println("La cajera " + this.nombre + " COMIENZA A PROCESAR LA COMPRA DEL CLIENTE " 
+ this.cliente.getNombre() + " EN EL TIEMPO: " 
+ (System.currentTimeMillis() - this.initialTime) / 1000 + "seg");
for (int i = 0; i < this.cliente.getCarroCompra().length; i++) { 
this.esperarXsegundos(cliente.getCarroCompra()[i]); 
System.out.println("Procesado el producto " + (i + 1) 
+ " del cliente " + this.cliente.getNombre() + "->Tiempo: " 
+ (System.currentTimeMillis() - this.initialTime) / 1000 + "seg"); }
System.out.println("La cajera " + this.nombre + " HA TERMINADO DE PROCESAR " 
+ this.cliente.getNombre() + " EN EL TIEMPO: " 
+ (System.currentTimeMillis() - this.initialTime) / 1000 + "seg"); }
private void esperarXsegundos(int segundos) {
try { Thread.sleep(segundos * 1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt(); } } }
Es imprescindible sobre-escribir el método “run()” (de ahí la etiqueta @Override) , ya q es un método 
que está en la clase Runnable y la clase Thread Implementa esa Interfaz, y xq en él se codifica la 
funcionalidad q se ejecuta en 1hilo; es decir, q lo q se programe en el método “run()” se va a ejecutar 
de forma secuencial en 1 hilo. En la clase “CajeraThread” se pueden sobre-escribir más métodos p/q 
hagan acciones sobre el hilo o thread como x ej., parar el thread, ponerlo en reposo, etc
CLASE “MAINTHREAD.JAVA“
public class MainThread {
public static void main(String[] args) {
Cliente cliente1 = new Cliente("Cliente 1", new int[] { 2, 2, 1, 5, 2, 3 });
Cliente cliente2 = new Cliente("Cliente 2", new int[] { 1, 3, 5, 1, 1 });
// Tiempo inicial de referencia
long initialTime = System.currentTimeMillis();
CajeraThread cajera1 = new CajeraThread("Cajera 1", cliente1, initialTime);
CajeraThread cajera2 = new CajeraThread("Cajera 2", cliente2, initialTime);
cajera1.start();
cajera2.start(); } }
El método Main de la clase “MainThread.java” procesa las compras de los clientes de forma paralela e 
independiente, y tarda solo 15 segundos en terminar su ejecución. 
CLASE “MAINTHREAD.JAVA“
public class MainRunnable implements Runnable{
private Cliente cliente;
private Cajera cajera;
private long initialTime;
public MainRunnable (Cliente cliente, Cajera cajera, long initialTime){
this.cajera = cajera;
this.cliente = cliente;
this.initialTime = initialTime;}
public static void main(String[] args) {
Cliente cliente1 = new Cliente("Cliente 1", new int[] { 2, 2, 1, 5, 2, 3 });
Cliente cliente2 = new Cliente("Cliente 2", new int[] { 1, 3, 5, 1, 1 });
Cajera cajera1 = new Cajera("Cajera 1");
Cajera cajera2 = new Cajera("Cajera 2");
// Tiempo inicial de referencia
long initialTime = System.currentTimeMillis();
Runnable proceso1 = new MainRunnable(cliente1, cajera1, initialTime);
Runnable proceso2 = new MainRunnable(cliente2, cajera2, initialTime);
new Thread(proceso1).start();
new Thread(proceso2).start(); }
@Override
public void run() {
this.cajera.procesarCompra(this.cliente, this.initialTime); } }
Otra forma es implementar la 
Interfaz “Runnable”. En este 
caso no se dispondrá ni se 
podrá sobre-escribir los 
métodos de la clase Thread
ya q no se van a utilizar y 
solo se va a tener q sobre-
escribir el método “run()“. 
Solo será necesario 
implementar el método 
“run()” p/q los procesos 
implementados en ese 
método se ejecuten en un 
hilo diferente. En este ej. se 
utiliza objetos de las clases 
“Cliente.java” y 
“Cajera.java” p/ 
implementar la multitarea.
• García de Jalón J, Rodríguez J, Mingo I, Imaz A, Brazalez A, Larzabal A, 
Calleja J y García J. 2.000. Aprenda Java como si estuviera en primero.
• Página web consultada, accedidas en Septiembre de 2.018: 
o http://jarroba.com/multitarea-e-hilos-en-java-con-ejemplos-thread-
runnable/
• Sánchez Jorge. 2.004. Java2 incluye Swing, Threads, programación en 
red, Javabeans, JDBC y JSP / Servlets.
BIBLIOGRAFÍA RECOMENDADA

Continuar navegando

Materiales relacionados