martes, 30 de diciembre de 2014

TEMA #13: THREAD

En este tema veremos la clase Thread y cómo usarla. La palabra Thread significa hilo; en el contexto de este curso (y de programación en general) lo vamos a definir como una tarea que puede realizarse simultáneamente con otra, y que nos va a permitir realizar procesos de manera simultánea. Podemos utilizar sólo un Thread dentro de nuestra aplicación/juego, o podemos utilizar varios simultáneamente.

¿Cómo Definir Un Thread?
Cuando trabajamos con una aplicación/juego podemos decidir si colocar un Thread “aislado” o crear una clase que implemente la interfaz Runnable. En este caso vamos a ver cómo usar un Thread “aislado”. El paquete que debemos importar a la hora de usar un Thread es java.lang.Thread;. Un Thread se define de la siguiente forma:

Definición
Notas
Thread th = new Thread(){
     public void run(){
           …
           try{
                 Thread.sleep(long milisecs);
           }catch(InterruptedException ie){}
     }
};
th.start();
Vemos la estructura del Thread... Dentro del método public void run(){...} debemos colocar las acciones que realizará el hilo.
Vemos que dentro debemos colocar también una línea de código que determinará cada cuanto tiempo trabajará el Thread y vemos que lanza un error el cual debemos capturar.
Por último iniciamos el Thread a través del método .start();.

Ejemplo: si tenemos un lienzo de dibujo y queremos que cada 5 segundos cambie de color, esto lo hacemos con Thread. Si queremos que una imagen se mueva de un lugar a otro continuamente, lo hacemos con Thread.

Como te habrás dado cuenta, en todas las aplicaciones de ejemplo la pantalla de presentación consiste en muchos círculos y un fondo que van cambiando poco a poco de color. Este efecto de cambio de color de poco a poco lo hacemos con Thread.


Redundancia de Thread
En mi experiencia con el uso de los Threads tuve un problema que me enseñó dos métodos de cómo evitar lo que yo llamo “redundancia de Thread”. Miremos el siguiente ejemplo gráfico con el cual explicaremos la redundancia de Thread:


Supongamos que estamos haciendo una aplicación que funcione como cronómetro y necesitamos que cada segundo se le sume 1 a la cuenta de los segundos y que se empiece a contar cuando se presione la tecla 1 del teclado de nuestro celular. Veamos el código de la imagen de acá arriba: el Thread que definimos se va a encargar de aumentar el valor de la cuenta (cuenta+=1;) y más abajo está cada cuánto tiempo se realizará la acción (Thread.sleep(1000);), que debe ser colocado en milisegundos. En este caso, cada 1 segundo (1000 milisegundos) se aumentará el valor de la variable cuenta en 1. Las últimas líneas determinan cuándo se iniciará el Thread, en este caso, cuando dentro de un lienzo de dibujo pulsemos la tecla 1 del teclado de nuestro celular.

Pero, ¿dónde está el problema?, ¿dónde ocurre la redundancia de Thread? Pues bien, dijimos que cuando pulsamos la tecla 1 del teclado de nuestro celular se inicia el Thread, ahora, si pulsamos nuevamente la tecla 1 cuando el Thread se está ejecutando se recibirá nuevamente la orden de iniciar el Thread. El efecto que causa la redundancia de Thread es que la velocidad del Thread se aumentará, deshaciendo así la coordinación del Thread. Esto no resulta útil porque en lugar de que se aumente el valor de la variable cuenta en 1 cada 1 segundo, se aumentará en 1 pero el tiempo será acortado (cada 0.5 segundos).

Descarga la aplicación de ejemplo donde se muestran los efectos de la redundancia de Thread. Descargar App.
Descarga el código y los recursos utilizados en esta aplicación. Descargar.



Métodos Para Evitar La Redundancia De Thread
Para evitar la redundancia de Thread me he dado cuenta de dos formas para evitarla, las llamaremos “Método de la llave” y “Método de confirmación”.

Método de la llave
Este método consiste en colocar una variable de tipo numérico (llave) que es la que va a determinar cuándo se inicia el Thread, y cuando se inicie el Thread, éste se encargará de cambiar el valor de la llave para que no se active nuevamente el Thread. Veamos el siguiente ejemplo gráfico:

En este ejemplo si pulsamos la tecla 1 del teclado de nuestro celular activará una llave que se encargará de activar el Thread. Una vez que el Thread se activa, el mismo Thread se encarga de desechar la llave para que cuando de pulse la tecla 1 nuevamente no ocurra la redundancia de Thread.

Ahora, ¿cómo creamos la llave y cómo la desechamos? Mencionamos anteriormente que la llave va a ser una variable de tipo int. Cuando creamos esta variable “creamos la llave”, cuando esta variable tenga un valor específico se activará el Thread (usamos la llave) y cuando el Thread se active se encargará de cambiar el valor de la variable (desechamos la llave).

Descarga un código donde se corrige el error de la aplicación del principio, utilizando este método. Descargar.
Descarga la aplicación. Descargar.

Método de confirmación
Este método consiste en utilizar la estructura de control if/else para confirmar si el Thread se encuentra ejecutándose o no, lo que nos permitirá activar el Thread, si no está activo, y en el caso de que esté activo, no hacer nada, evitando la redundancia de Thread. Veamos el siguiente ejemplo gráfico:

Vemos que para que se realice la acción primero se pasa por un filtro para confirmar que el Thread no se encuentre activo. Si no se encuentra activo se inicia (thr.start();), pero si ya se encuentra activo no se realiza ninguna acción.

Nota: para utilizar este método es indispensable que los Threads que utilicemos los coloquemos al principio y los definamos como un Thread vacío:

private Thread thr = new Thread();

Si no se hace esto no funcionará el método de confirmación.

Descarga un código donde se corrige el error de la aplicación del principio, utilizando este método. Descargar.
Descarga la aplicación. Descargar.

Por último te dejo la porción de código que corresponde a la pantalla inicial de las aplicaciones de ejemplo a lo largo del curso. Descargar.

No hay comentarios.:

Publicar un comentario