Documento Adjunto-Java PDF
Documento Adjunto-Java PDF
Documento Adjunto-Java PDF
CAPITULO 12
Programación de Hilos
Objetivos
• Utilizar la clase Timer para manejo de procesos que requieran
ser controlados según intervalos de tiempo dados.
• Caracterizar aplicaciones que manejen multiples tareas
• Desarrollar aplicaciones que permitan manejar animaciones.
• Utilizar la clase Thread y la interface Runnable para el manejo
de hilos desde un programa.
• Indicar los elementos necesarios para el manejo de la
sincronización de procesos
•
Introducción
En la naturaleza se presentan innumerables ejemplos de procesos que se
realizan de manera parela, simultáneos o concurrentes. Por ejemplo, para el
caso del lector, los procesos que está realizando todo su cuerpo integral,
mientras realiza la acción consciente, de leer este párrafo. En el plano de los
sistemas artificiales, la concurrencia es un denominador común, el computador,
la internet, los juegos, en los sistemas sofisticados de los automóviles
modernos, las actuales comunicaciones inalambricas, etc.
Hasta el momento se han desarrollado programas que realizan una sola tarea,
entendiendose por tarea, un hilo de ejecución o un thread, tambien
denominados de flujo único, en contraste con los programas que realizan más
de una tarea, o de multitareas o multithreads, denominados de flujo múltiple.
Especificamente una tarea se encarga de controlar un único aspecto, dentro de la
ejecución de un programa, por ejemplo el manejo de gráficos, las
entradas/salidas de archivos en disco, u otros. Las tareas se diferencian de los
procesos, en que las primeras comparten los mismos recursos del programa que
las contiene, en tanto los procesos tienen en forma separada su código, así
como sus datos.
Se puede definir hilo como una secuencia única de control de flujo dentro de un
programa. Entendiendo que puede haber más de una secuencia de control o
hilos. Java permite realizar programación multihilo, el cual consiste en
programas que contienen dos o más partes que se ejecutan de manera
concurrente. Una parte que se ejecuta independientemente de las demás se
denomina un hilo (thread).
las velocidades de transmisión son mucho más lentas que los requeridos por la
CPU en el procesamiento de esos datos, así como tambien durante el manejo
del sistema de archivos, lectura y grabación, que son más lentos que las
velocidades de la CPU en su proceso. Las animaciones y los juegos por
ejemplo, requieren de una mayor optimización de los recursos de CPU.
dos hilos
un hilo
Un hilo puede detenerse sin afectar las otras partes del programa. Por ejemplo
en un hilo de animación, se hace que los bucles de la animación se detengan
durante un tiempo, un segundo, sin hacer que se pare el resto del programa.
Cuando un hilo se detiene o se bloquea, sólo el se detiene y los demás
continúan con su ejecución.
• Listo: Cuando se invoca el método start() del hilo, se dice que está en
estado listo. El método se arranca con la siguiente instrucción, para el caso
del hilo miHilo:
miHilo.start();
El método stop() provoca una terminación súbita del método run() del hilo.
Si el método run() estuviera realizando cálculos sensibles, stop() podría
dejar el programa en un estado inconsistente. Normalmente, no se debería
Programación de Hilos: Ciclo de vida de un hilo 12 - 7
La clase Thread
Como ya se ha establecido antes, un thread es un hilo de ejecución de un
programa. La Maquina Virtual de Java (JVM) permite la ejecución de
concurrente de múltiples hilos. En la clase Thread se encapsula todo el control
necesario sobre los hilos de ejecución o tareas. Un objeto Thread se lo puede
entender como el panel de control sobre una tarea o hilo de ejecución. Dispone
de métodos para controlar el comportamiento de las tareas, los cuales se tratarán
más adelante.
Prioridades
El intérprete de Java utiliza prioridades, como valores enteros, para determinar
el trato que le debe dar a cada hilo respecto de los demás. La prioridad de un
hilo se utiliza para determinar cúando se pasa a ejecutar otro hilo, lo cual se
denomina cambio de contexto de ejecución. Hilos con alta prioridad se ejecutan
preferencialmente sobre hilos de menor prioridad.
El hilo principal
Cuando la Maquina Virtual de Java arranca la ejecución de un programa, ya hay
un hilo ejecutándose, denominado hilo principal del programa, que se ejecuta
cuando comienza el programa. Su importancia radica en que:
• Debe ser el último hilo que termine su ejecución, ya que cuando este hilo
finaliza, el programa termina.
Creación de hilos
El método run() le permite a un hilo realizar su tarea, ya que su código
implementa el comportamiento de ejecución de la clase Thread, pudiendo
realizar cualquier operación que sea codificable en instrucciones Java.
La clase Thread implementa un hilo genérico que por defecto no realiza nada,
es decir que, la implementación de ese método dentro de la clase es vacía. La
clase Thread (que es de por sí un objeto Runnable) permite que un objeto
Runnable provea un método run() más interesante para los hilos. Hay dos
manera de crear hilos:
instancia de esta clase. Esta nueva clase debe sobreescribir el método run de la
clase Thread que es el punto de entrada del nuevo hilo. Dentro de la clase que
utilice la instancia de la clase Thread, se debe llamar al método start() para que
inicie la ejecución del nuevo hilo.
La siguiente es la forma general del cuerpo de una clase hilo mediante extensión
de la clase Thread:
public class NombreClase extends Thread{
// clase que extiende a Thread
.....
public void run(){
// cuerpo para sobreescribir run()
.....
}
}
Dentro de la clase que usa a NombreClase, la siguiente es la forma del
código para crear el hilo e iniciar su ejecución mediante el llamado al método
start():
NombreClase unHilo = new NombreClase();
.
.
unHilo.start();
System.out.println("Numero "+i);
try {
sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupcion hilo ");}
}
System.out.println("Termina hilo " );
}
}
import javax.swing.JOptionPane;
public class UsaGeneraEnteros{
public static void main (String[] args) {
int numero = Integer.parseInt
(JOptionPane.showInputDialog("Cuantos terminos?"));
GeneraEnteros serie =new GeneraEnteros(numero);
serie.start();
}
}
try {
for (int i = 0; i <5; i++) {
System.out.println("valor i = "+i+" en Hilo principal
en main()");
Thread.sleep(3000);
}
}catch (InterruptedException e){
System.out.println("Interrupci¢n del hilo principal en
main()");
}
System.out.println("Termina Hilo principal en main()");
}
}
Numero 2 en hilo 1
valor i = 1 en Hilo principal en main()
Numero 3 en hilo 1
Numero 4 en hilo 1
Numero 5 en hilo 1
valor i = 2 en Hilo principal en main()
Numero 6 en hilo 1
Numero 7 en hilo 1
Numero 8 en hilo 1
valor i = 3 en Hilo principal en main()
Numero 9 en hilo 1
Termina hilo 1
valor i = 4 en Hilo principal en main()
Termina Hilo principal en main()
Exit code: 0
No Errors
try {
for (int i = 0; i <5; i++) {
System.out.println("valor i = "+i+" en Hilo principal
en main()");
Thread.sleep(3000);
}
}catch (InterruptedException e){
System.out.println("Interrupci¢n del hilo principal en
main()");
}
System.out.println("Termina Hilo principal en main()");
}
}
try {
for (int i = 0; i <5; i++) {
System.out.println("valor i = "+i+" en Hilo principal
en main()");
Thread.sleep(3000);
}
}catch (InterruptedException e){
System.out.println("Interrupci¢n del hilo principal en
main()");
}
System.out.println("Termina Hilo principal en main()");
Programación de Hilos: Creación de hilos 12 - 16
}
}
La siguiente forma general crea el hilo e inicia su ejecución en la clase que usa a
MiClase:
MiClase miHilo = new MiClase();
new Thread(miHilo).start();
import javax.swing.JOptionPane;
public class UsaGeneraEnterosRun{
public static void main (String[] args) {
int numero = Integer.parseInt
(JOptionPane.showInputDialog("Cuantos terminos?"));
GeneraEnterosRun serie1 =new GeneraEnterosRun(numero,
"hilo 1", 1000);
new Thread(serie1).start();
try {
for (int i = 0; i <5; i++) {
System.out.println("valor i = "+i+" en Hilo principal
en main()");
Thread.sleep(3000);
}
}catch (InterruptedException e){
System.out.println("Interrupci¢n del hilo principal en
main()");
}
System.out.println("Termina Hilo principal en main()");
}
}
try {
Thread.sleep(tiempo);
} catch (InterruptedException e) {
System.out.println("Interrupcion del hilo ");}
}
System.out.println("Termina hilo " );
unHilo= null;
}
}
public void paint(Graphics g){
g.drawString("Generación enteros ",x,y);
}
}
}
}
Los resultados al ejecutarse son los siguientes:
valor i = 0 en Hilo principal en main()
Numero 0 en hilo 1
Numero 0 en hilo 2
Numero 1 en hilo 2
Numero 2 en hilo 2
Numero 3 en hilo 2
Numero 4 en hilo 2
Numero 5 en hilo 2
Numero 1 en hilo 1
Numero 6 en hilo 2
Numero 7 en hilo 2
Numero 8 en hilo 2
Numero 9 en hilo 2
Numero 2 en hilo 1
Termina hilo 2
valor i = 1 en Hilo principal en main()
Numero 3 en hilo 1
Numero 4 en hilo 1
Numero 5 en hilo 1
valor i = 2 en Hilo principal en main()
Numero 6 en hilo 1
Programación de Hilos: Creación de hilos 12 - 22
Numero 7 en hilo 1
Numero 8 en hilo 1
valor i = 3 en Hilo principal en main()
Numero 9 en hilo 1
Termina hilo 1
valor i = 4 en Hilo principal en main()
Termina Hilo principal en main()
Exit code: 0
No Errors
La salida es la siguiente:
}
}
public void run() {
Thread thisThread = Thread.currentThread();
while (runner == thisThread ) {
for(int i=1; i <= 100;i++){
repaint();
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
}
System.out.println("Termina hilo");
runner= null;
}
}
public void paint(Graphics g) {
}
}
animationThread.stop();
circles.removeAllElements();
}
}
repaint();
}
import java.awt.*;
setDeltaY(-deltaY);
}
public int getDeltaX() {
return(deltaX);
}
public void setDeltaX(int deltaX) {
this.deltaX = deltaX;
}
public int getDeltaY() {
return(deltaY);
}
public void setDeltaY(int deltaY) {
this.deltaY = deltaY;
}
}
<HTML>
<BODY BGCOLOR="WHITE"><H1>Circulos rebotando</H1>
<TABLE BORDER=5> <TR><TH>
<APPLET CODE="Bounce.class" WIDTH=600 HEIGHT=400> </APPLET>
</TABLE></BODY> </HTML>