Programación Java

Anuncio
Práctica 11
San Sebastián, mayo 1999
Programación Java
Javier García de Jalón · José Ignacio Rodríguez
Alfonso Brazález · Alberto Larzabal · Jesús Calleja · Jon García
Informática 2: Práctica nº 11
página 1
INDICE
Ejercicio 1:
Ejercicio 2:
Ejercicio 3:
Ejercicio 4:
Ejercicio 5:
Ejercicio 6:
Crear una aplicación sencilla que arranque un thread............................................................... 1
Crear una aplicación que arranque dos threads ........................................................................ 2
Crear una aplicación que arranque tres threads ........................................................................ 2
Crear una aplicación gráfica con tres threads que simule una carrera ....................................... 2
Nodificar el ejercicio anterior para simular una carrera con prioridades ................................... 5
Crear la aplicación Reloj......................................................................................................... 5
Antes de comenzar la práctica abre el Windows Explorer y comprueba que se ha creado de modo
automático en tu disco G:\ un directorio llamado Inf2prac11. No deberás moverlo a otro
subdirectorio ni cambiarle de nombre. Por motivos de orden es importante que todos los ejercicios
de esta práctica se creen dentro de este directorio, porque esta semana se recogerá la práctica.
Como recomendación general, mantén abierto el Windows Explorer y comprueba de vez en
cuando que los proyectos de los distintos ejercicios se están guardando correctamente. Hay que
evitar copiar los ejercicios de otra persona, principalmente porque así no se aprende a programar: a
programar sólo se aprende programando.
Puedes utilizar también Windows Explorer para ayudar a Visual J++ 6.0 a crear un proyecto
nuevo a partir de los ficheros del anterior.
Ejercicio 1:
Crear una aplicación sencilla que arranque un thread
En este ejercicio se trata de crear una clase derivada de Thread llamada SimpleThread. El siguiente
programa crea un thread con nombre “Jamaica”. El método run() de este thread imprime diez
veces un mensaje con el número y el nombre del thread, esperando un tiempo aleatorio entre cero y
tres segundos.
El programa principal main() crea un thread y los arranca. Como el entorno Visual J++ cierra
la consola y la aplicación en cuanto termina la ejecución, sin permitir ver con calma los resultados,
se ha incluido una “espera” por medio de un mensaje y la lectura de un carácter, que debe
producirse antes de terminar la aplicación.
Crea un proyecto llamado Ejer1 que contenga el siguiente fichero:
// fichero SimpleThread.java
import java.io.*;
public class SimpleThread extends Thread {
// constructor
public SimpleThread(String name) {
super(name);
}
// método principal del thread
public void run() {
for (int i=0; i<10; i++) {
System.out.println(i + " " + getName());
try {
sleep((int)(Math.random()*3000));
} catch (InterruptedException e) {}
}
System.out.println("Done!" + getName());
}
Informática 2: Práctica nº 11
página 2
// programa principal
public static void main (String[] args) {
// se crea un thread con el nombre "Jamaica"
SimpleThread st1 = new SimpleThread("Jamaica");
// se arranca el thread
st1.start();
// se espera a pulsar Intro para terminar
try {
while (currentThread().activeCount() > 1) {
currentThread().sleep(100);
}
System.out.print("Pulse return para finalizar ");
System.in.read();
} catch (IOException e) {}
catch (InterruptedException ie) {}
}
} // fin de la clase SimpleThread
En realidad este programa utiliza dos threads: uno creado explícitamente y otro el thread en
el que corre el programa main(). Si no se indica nada y para esperar se pone simplemente el código
try {
System.out.print("Pulse return para finalizar ");
System.in.read();
} catch (IOException e) {}
el mensaje de “Pulse return…” se escribe antes que los diez mensajes del thread puesto que el
thread de main() se puede ejecutar más rápidamente (la “espera” a que el usuario teclee un carácter
siempre queda al final, pero no el mensaje citado). Para evitar esto se he introducido un bucle de
espera basado en un while que pregunta el número de threads abiertas: mientras haya más de un
thread activo se espera; cuando sólo queda el thread del programa principal se imprime el mensaje.
Ejercicio 2:
Crear una aplicación que arranque dos threads
Crea un proyecto llamado Ejer2 con Visual J++ en el directorio de la práctica Inf2prac11. Copia a
este directorio el fichero SimpleThread.java. Cambia el nombre al fichero anterior y llámale
SimpleThread2.java. Abre el fichero SimpleThread2.java y cambia el nombre de la clase
SimpleThread para que se llame SimpleThread2. Cambia este nombre en el constructor, en el
programa principal y en todas las sentencias en que sea necesario. Ejecuta el programa para
comprobar que todo funciona correctamente.
Modifica el programa main() para que cree dos threads, llamados “Jamaica” y “Fiji”.
Después de crearlos, arráncalos con el método start(). Ejecuta el programa algunas veces para ver
qué isla termina primero. ¿Piensas que tiene alguna importancia el orden en el que se arrancan los
threads?
Ejercicio 3:
Crear una aplicación que arranque tres threads
Este ejercicio es completamente análogo al anterior, pero creando tres threads en lugar de dos.
Llámeles “Jamaica”, “Fiji” y “Canarias”. El proyecto se llamará Ejer3 y la clase SimpleThread3.
Ejercicio 4:
Crear una aplicación gráfica con tres threads que simule una carrera
Este ejercicio es similar al anterior, pero en este caso la carrera se va a poder seguir gráficamente en
una ventana derivada de VentanaCerrable. Se trata de crear una ventana de 200x350 pixels, situada
Informática 2: Práctica nº 11
página 3
a una distancia (100x100) pixels de la esquina superior izquierda de la pantalla, que responda al
evento Closing en los controles de la propia ventana, y que presente el aspecto mostrado en la
Figura 1.
Figura 1. Carrera entre tres threads.
Crea un proyecto llamado Ejer4. A continuación se muestra el “esqueleto” de la aplicación
que hay que desarrollar. Este esqueleto deberá ser completado hasta que el programa funcione como
el modelo, que está en el directorio Q:\Infor2\Prac11\Ejer4. El fichero Esqueleto.java, que está
también en dicho directorio, te permitirá comenzar más fácilmente la aplicación.
// fichero Carrera3.java
import java.awt.*;
import java.awt.event.*;
public class Carrera3 extends VentanaCerrable implements ActionListener {
// variables miembro
MiPanel mp;
// panel en que se harán los dibujos
MiThread mt1,mt2,mt3; // las tres threads
// programa principal
public static void main (String[] args) {
...
}
// constructor
public Carrera3(String titulo) {
super(titulo);
// se crea un objeto clese MiPanel
...
// se crea el botón que arrancará las threads
...
// se registra el event listener
...
// se añade el botón dentro de un panel
...
// se crean los tres threads
...
}
// método para gestionar el botón "Start"
public void actionPerformed(ActionEvent e){
... // se arrancan los threads
}
} // fin clase Carrera3
Informática 2: Práctica nº 11
página 4
// clase MiPanel que redefine el método paint()
class MiPanel extends Panel {
// variables miembro
//
posición de cada corredor y de la meta
public int x1, x2, x3, finish;
// constructor
public MiPanel () {
...
}
// redefinir el método paint()
public void paint(Graphics g) {
...
// segundo corredor
...
// tercer corredor
...
// se dibuja la meta
...
}
} // fin clase MiPanel
// clase MiThread que define el método run()
class MiThread extends Thread {
// Variable miembro
// referencia a MiPanel para poder dar valor a x1, x2 y x3
MiPanel mp;
// constructor
public MiThread(String str, MiPanel mip) {
...
}
// método run()
public void run() {
boolean running = true;
// se obtiene la posición de la meta del objeto m
int finish = mp.finish;
// condición para terminar el método run()
while(running){
// se para el thread unos milisegundos
try {
sleep((int)(Math.random()*500));
} catch (InterruptedException e) {}
...
// habiendo cambiado un móvil, se vuelve a dibujar
...
}
// se avisa que el corredor ha llegado a la meta
System.out.println("El corredor " + getName()+" ha llegado!");
} // fin run()
} // fin clase MiThread
Como ya se ha dicho, como modelo de este ejercicio pueden utilizarse los ficheros *.class que
están en el directorio q:\Infor2\Prac11\Ejer4.
Informática 2: Práctica nº 11
Ejercicio 5:
página 5
Nodificar el ejercicio anterior para simular una carrera con prioridades
Este ejercicio es muy similar al anterior. Crea un proyecto llamado Ejer5 y copia en él el fichero
Carrera3.java. Cámbiale el nombre a Carrera3Prioridades.java. Haz los cambio de nombre
pertinentes dentro del fichero y comprueba que todo funciona correctamente.
Para ver el efecto de las distintas prioridades se deben hacer los siguientes cambios:
1. En vez de esperar cada thread un número de milisegundos aleatorio (lo cual siempre da
una oportunidad a las demás threads para ejecutarse, sea cual sea su prioridad), la espera
se realizará de forma activa, por ejemplo incrementando una variable entera un millón de
veces. De esta forma los distintos threads tendrán que disputarse el tiempo de la CPU y el
efecto de las prioridades será patente.
2. Después de crear los objetos de la clase thread asígnales tres prioridades diferentes, como
por ejemplo los valores: Thread.NORM_PRIORITY-2, Thread.NORM_PRIORITY
Thread.NORM_PRIORITY+2. Esto se puede hacer con el método setPriority().
Ejecuta el programa y comprueba la diferencia entre las prioridades anteriores y el asignar a
todos los threads la misma prioridad, por ejemplo Thread.NORM_PRIORITY.
Como modelo de este ejercicio pueden utilizarse los ficheros *.class que están en el directorio
q:\Infor2\Prac11\Ejer5.
Ejercicio 6:
Crear la aplicación Reloj
Este último ejercicio, cuyo proyecto se llamará Ejer6, está destinado a mostrar cómo interaccionan
dos threads que continen dos tipos de tareas muy diferentes:
1. Una con una gran cantidad de cálculos, y
2. Otra con muy poco trabajo pero que debe ser muy puntual (un reloj que tiene que mostrar
cada segundo que pasa).
En estos casos es conveniente dar la mínima prioridad al thread que tiene la tarea más pesada.
Es muy poco significativo que la tarea pesada tarde unos milisegundos más y a cambio se consigue
que el reloj funcione correctamente.
La Figura 2 muestra la ventana principal de esta aplicación. En la parte superior hay una barra
que va creciendo de pixel en pixel contando de 0 a un millón cada vez que crece. En el centro se
muestra un rótulo que indica el tiempo en segundos desde el comienzo de la ejecución.
Figura 2. Ventana de la aplicación Reloj.
Pueden utilizarse como modelo los ficheros *.class de este ejercicio, que están en el directorio
q:\Infor2\Prac11\Ejer6.
Informática 2: Práctica nº 11
página 6
Descargar