Applets Java


En esta página:

  • Ejecución multihilo en applets

Ejecución multihilo en applets

Hasta ahora sólo disponíamos de un hilo de ejecución. Es decir, en nuestros programas sólo se ejecuta una cosa al tiempo. Si deseamos que se ejecuten varias cosas a la vez o simplemente deseamos disponer de una manera precisa de controlar la ejecución de parte de nuestro programa dependiendo del tiempo, necesitaremos que nuestro applet realice una ejecución multihilo.

El concepto de multitarea es diferente al de multihilo. El primero se suele aplicar a la ejecución concurrente de programas distintos, ya que para que exista multitarea se exige que cada proceso ejecutándose disponga de su propio espacio en la memoria. En el segundo caso, en cambio, todos los hilos que se ejecutan concurrentemente disponen del mismo espacio de memoria.

Pero no vamos a escribir un tratado filosófico sobre las diversas formas de programación concurrente. Lo mejor que podemos hacer es explicarlo sobre un ejemplo. El ejemplo siguiente es una modificación del applet MostrarMensaje, realizado anteriormente, que realiza un scroll lateral del texto, que aparece por la derecha y desaparece por la izquierda. El código nuevo que concierne a la ejecución multihilo está en negrita para facilitar su identificación:

Rotacion.java
/**
 * Applet MostrarCadena
 *
 * <APPLET CODE="MostrarCadena.class" WIDTH="200" HEIGHT="70">
 *   <PARAM NAME="Cadena" VALUE="Esto sí que es chulo">
 * </APPLET>
 */

import java.applet.Applet;
import java.awt.*;

public class MostrarCadena extends Applet implements Runnable {
  String mensaje;
  int lugar;
  Thread hilo = null;
  public void init() {
    mensaje = getParameter("cadena");
    if (mensaje==null)
      mensaje = "Mensaje por defecto";
    lugar = getBounds().width;
  }
  public void start() {
    if (hilo==null) {
      hilo = new Thread(this);
      hilo.start();
    }
  }
  public void stop() {
    hilo = null;
  }
  public void paint(Graphics g) {
    g.drawString(mensaje,lugar,20);
  }
  public void run() {
    while (hilo!=null && hilo.isAlive()) {
      lugar -= 1;
      repaint();
      try {
        hilo.sleep(10);
      }
      catch (InterruptedException e) {} // No hacemos nada
    }
  }
}

Lo primero es asegurarnos que nuestro applet implementa el interfaz Runnable, necesario para el soporte de threads, o hilos de ejecución. Después declaramos un objeto de tipo Thread, es decir, hilo, y lo igualamos a null. En el método start(), que es donde debe "estart" todo el código de inicialización, creamos el hilo y lo arrancamos llamando a su método start(). En stop(), por el contrario, lo paramos.

El método run() es nuevo y es consecuencia de la implementación del interfaz Runnable. Cuando creamos un hilo de ejecución, como hemos hecho en start(), el hilo recién creado siempre comienza su vida útil ejecutando el método run(). Así pues, aquí estará el código del hilo. Comenzamos preguntando si existe nuestro hilo (hilo!=null) y si está ejecutandose (isAlive).

Luego mueve el texto un poco a la izquierda, repinta, y se obliga a sí mismo a dejar de ejecutarse durante 10 milisegundos por medio del método sleep(). Transcurrido ese tiempo seguirá su ejecución por el mismo sitio donde la dejó (de ahí que sea necesario el while).

Indicar por último que es obligatorio capturar la excepción InterruptedException para poder llamar al método sleep(). En caso contrario el compilador se queja. Así pues, lo hacemos, aunque no especifiquemos ningún código en caso de que se lance dicha excepción. Esto ocurrirá en casos muy excepcionales, por lo que no debemos preocuparnos.