##
ARRANCAR Y PARAR THREADS

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]