Ahora que ya hemos visto por encima como se arrancan, paran y manipulan threads, vamos a mostrar un ejemplo un poco más gráfico, se trata de un contador, cuyo código (App1Thread.java) es el siguiente:
import java.awt.*; import java.applet.Applet; public class App1Thread extends Applet implements Runnable { Thread t; int contador; public void init() { contador = 0; t = new Thread( this ); t.start(); } public void run() { while( true ) { contador++; repaint(); try { t.sleep( 10 ); } catch( InterruptedException e ) { ; }; } } public boolean mouseDown( Event evt,int x,int y ) { t.stop(); return( true ); } public void paint( Graphics g ) { g.drawString( Integer.toString( contador ),10,10 ); System.out.println( "Contador = "+contador ); } public void stop() { t.stop(); } }
Este applet arranca un contador en 0 y lo incrementa, presentando su salida tanto en la pantalla gráfica como en la consola. Una primera ojeada al código puede dar la impresión de que el programa empezará a contar y presentará cada número, pero no es así. Una revisión más profunda del flujo de ejecución del applet, nos revelará su verdadera identidad.
En este caso, la clase App1Thread está forzada a
implementar Runnable sobre la clase Applet que extiende.
Como en todos los applets, el método init() es el
primero que se ejecuta. En init(), la variable contador
se inicializa a cero y se crea una nueva instancia de la clase
Thread. Pasándole this
al constructor de
Thread, el nuevo thread ya conocerá al objeto que va a
correr. En este caso this
es una referencia a App1Thread.
Después de que hayamos creado el thread, necesitamos arrancarlo.
La llamada a start(), llamará a su vez al método
run() de nuestra clase, es decir, a App1Thread.run().
La llamada a start() retornará con éxito
y el thread comenzará a ejecutarse en ese instante. Observar
que el método run() es un bucle infinito. Es infinito
porque una vez que se sale de él, la ejecución del
thread se detiene. En este método se incrementará
la variable contador
, se duerme 10 milisegundos y envía
una petición de refresco del nuevo valor al applet.
Es muy importante dormirse en algún lugar del thread, porque
sino, el thread consumirá todo el tiempo de la CPU para
su proceso y no permitirá que entren otros métodos
de otros threads a ejecutarse. Otra forma de detener la ejecución
del thread es hacer una llamada al método stop().
En el contador, el thread se detiene cuando se pulsa el ratón
mientras el cursor se encuentre sobre el applet. Dependiendo de
la velocidad del ordenador, se presentarán los números
consecutivos o no, porque el incremento de la variable contador
es independiente del refresco en pantalla. El applet no se refresca
a cada petición que se le hace, sino que el sistema operativo
encolará las peticiones y las que sean sucesivas las convertirán
en un único refresco. Así, mientras los refescos
se van encolando, la variable contador
se estará
todavía incrementando, pero no se visualiza en pantalla.
|
[Anterior] [Indice] [Siguiente] |