viernes, 19 de octubre de 2012

Manejo de Threads (Metodos)

Los métodos start() y run()
Como habíamos mencionado antes, para poner en marcha este nuevo Thread se debe llamar al método start(), heredado de  la súper-clase Thread, que se encarga de llamar a run(). Es importante no confundir el método start() con el método run(). El método run() contiene el código a ser ejecutado “asincrónicamente” en otro thread, mientras que el método start() es el que crea al Thread y en algún punto hace que ese Thread ejecute lo que esta en run(). Este método devuelve el control inmediatamente. Pero si mezclamos todo y ejecutamos directamente el run(), el código se ejecutara en el Thread actual.

El método start() devuelve el control inmediatamente… mientras tanto, el nuevo Thread inicia su recorrido por el método run(). ¿Hasta cuando? Hasta que termina ese método, cuando sale, termina el Thread.

El método join()
Si un Thread necesita esperar a que otro termine (por ejemplo el Thread padre espera a que termine el hijo) puede usar el método join(). ¿Por que se llama así? Crear un proceso es como una bifurcación, se abren 2 caminos, que uno espere a otro es lo contrario, una unificación.


A continuación se presenta un ejemplo más complejo: una reunión de alumnos. El siguiente ejemplo usa Threads para activar simultáneamente tres objetos de la misma clase, que comparten los recursos del procesador peleándose para escribir a la pantalla.

public static void main(String args[]) throws InterruptedException{

       Thread juan = new Thread (new Alumno(“Juan”));
       Thread luis = new Thread (new Alumno(“Luis”));
       Thread nora = new Thread (new Alumno(“Nora”));
      
       juan.start();
       juan.join();

       pepe.start();
pepe.join();

       jorge.start();
jorge.join();
}
El metodo join() que llamamos al final hace que el programa principal espere hasta que este Thread este “muerto”(finalize su ejecucion). Este método puede disparar la excepción InterruptedException, por lo que lo hemos tenido en cuenta en el encabezamiento del método.

En nuestro ejemplo, simplemente a cada instancia de Alumno(…) que creamos la hemos ligado a un Thread y puesto a andar. Corren todas en paralelo hasta que mueren de muerte natural, y también el programa principal termina.

A continuación se muestra la clase Alumno:

class Alumno implements Runnable{

String mensaje;

public Alumno(String nombre){

      mensaje = “Hola, soy “ + nombre + “ y este es mi mensaje numero: “;

}

public void run(){

      for (int i=1; i<6;i++){
                      String msj = mensaje + i;
                      System.out.println(msj);
      }

}

La salida será más o menos así:

Hola, soy Juan y este es mi mensaje numero 1
Hola, soy Juan y este es mi mensaje numero 2
Hola, soy Juan y este es mi mensaje numero 3
Hola, soy Juan y este es mi mensaje numero 4
Hola, soy Juan y este es mi mensaje numero 5
………….etc.

El método yield()
El método yield() tiene la función de hacer que un hilo que se está ejecutando de regreso al estado en “listo para ejecutar” para permitir que otros hilos de la misma prioridad puedan ejecutarse. Sin embargo, el funcionamiento de este método (al igual que de los hilos en general) no está garantizado, puede que después de que se establezca un hilo por medio del método yield() a su estado “listo para ejecutar”, éste vuelva a ser elegido para ejecutarse. El método yield() nunca causará que un hilo pase a estado de espera/bloqueado/dormido, simplemente pasa de ejecutándose(running) a  “listo para ejecutar”.
A continuación tomando el ejemplo anterior solo haremos una modificación en el método run, vemos como se implementa dicho metodo:

public void run(){
       for (int i=1; i<6; i++){
                       String msj = mensaje + i;
                       System.out.println(msj);
                       Thread.yield();
       }
}

En este ejemplo la salida será más o menos así:

Hola, soy Juan y este es mi mensaje 1
Hola, soy Luis y este es mi mensaje 1
Hola, soy Nora y este es mi mensaje 1

Hola, soy Juan y este es mi mensaje 2
Hola, soy Luis y este es mi mensaje 2
Hola, soy Nora y este es mi mensaje 2

Hola, soy Juan y este es mi mensaje 3
Hola, soy Luis y este es mi mensaje 3
…………etc.

El método sleep()
El método sleep() simplemente le dice al Thread que duerma durante los milisegundos específicos. Se debería utilizar sleep() cuando se pretenda retrasar la ejecución del Thread, sleep() no consume recursos del sistema mientras el Thread duerme. De  esta forma otros Threads seguir funcionando.

       objThread.sleep(1000) //Duerme al hilo objThread 1 seg

El método currentThread()
Para saber qué hilo se encuentra en ejecución en un momento determinado, existe el método estático Thread.currentThread().
Thread.currentThread().getName() te devuelve un valor de tipo cadena con el nombre del hilo en ejecución, si no has definido un nombre con el método setName(), de igual manera el proceso lo tendrá, algo muy parecido a Thread-0, Thread-1, etc.

El método suspend() –Deprecado(No se debe utilizar) –
Puede resultar útil suspender la ejecución de un Thread sin marcar un límite de tiempo. Si, por ejemplo, esta construyendo un applet con un Thread de animación, querrá permitir al usuario la opción de detener la animación hasta que quiera continuar. No se trata de terminar la animación, sino desactivarla. Para este tipo de control de Thread se puede utilizar el método suspend().

       objThread.suspend();

-Ver explicación de porque esta deprecado o porque no se debe utilizar -

El método resume() –Deprecado(No se debe utilizar) –
El método suspend() no detiene la ejecución permanente. El Thread queda suspendido indefinidamente y para volver a activarlo de nuevo necesitamos realizar una invocación al método resume();
       objThread.resume();

-Ver explicación de porque esta deprecado o porque no se debe utilizar -

El método stop() – Deprecado (No se debe utilizar) –
El método stop() da una muerte abrupta a un hilo.
       objThread.stop();

-Ver explicación de porque esta deprecado o porque no se debe utilizar -

12 comentarios:

  1. Gracias muy buena la pagina
    tengo una inquietud no me funciona el yield()
    y creo que hay un error aca ,porque pepe y jorge no son lo objectos creados
    public static void main(String args[]) throws InterruptedException{

    Thread juan = new Thread (new Alumno(“Juan”));
    Thread luis = new Thread (new Alumno(“Luis”));
    Thread nora = new Thread (new Alumno(“Nora”));

    juan.start();
    juan.join();

    pepe.start();
    pepe.join();

    jorge.start();
    jorge.join();
    }

    ResponderEliminar
  2. una consulta...si utilizo un metodo dentro del thread funcionaria por ejemplo tengo un metodo de listar() registro de la base de datos....en vez de dar click y seleccionar listar...que haga el listado automaticamente cuando se elimina el registro o se modifica,o se agrega...ojala puedan ayudarme...en mi proyecto desde ya gracias. ..

    ResponderEliminar
  3. Muchas gracias, crack me re ayudaste. Tenes un lugar para que te done btc, no es mucho pero algo es algo.

    ResponderEliminar