Tuesday, April 30, 2013

Concurrencia en Java Parte 1


Hola, voy a tratar de devolver un poco el conocimiento que he adquirido a través de los años al leer blogs, para esto voy a empezar con una serie de artículos en los cuales explicare el API de concurrencia de java, espero puedan aprender algo de esto como yo lo hice

Que es un thread?
El término concurrencia significa tareas ejecutandose simultáneamente, en java la concurrencia se soporta mediante objetos Thread. Un thread es un tarea de ejecución en un programa. La JVM permite a una aplicación tener múltiples threads que se ejecutan simultáneamente.

Existen 2 tipos de thread en java, los daemon y los no-daemon, cuando la JVM se inicia, por lo general hay un solo thread no-daemon y el que manda llamar al método main () de un programa, y la JVM se ejecuta hasta que una llamada a System.exit () se haga o todos threads que no son daemon hayan muerto.

En otras palabras los daemon thread  pueden llamarse thread del sistema y losno-daemon thread, pueden ser llamados threads de programa o threads de usuario, y una aplicación se ejecuta hasta que no queden threads de usuario o programa ejecutandose.

Exisen 2 formas de crear un thread:

      1. Extendiendo la clase  y sobreescribiendo el metodo run().
                 public class Calculador extends Thread {
                      public void run() {
                           .....
                     }
        }
  1. Implement the Runnable interface and  then create a Thread object and set the Runnable object to it.
                public class Calculador implements Runnable {
                     public void run() {
                         .....
                     }
                 }

Ya sea que el thread  extienda la clase Thread o implemente la interfaz Runnable, al final un objeto Thread tiene que ser creado para ejecutar el thread. Pero la creación de un objeto Thread en si no crea un nuevo thread de ejecución, sólo al llamar al método start() hace que se mande crear un nuevo thread de ejecución.

      1.    Si el objeto thread extendie Thread: 
                   Calculador calculador = new Calculador ();    
                   calculador.start(); 
      2.    Si el objeto thread implementa Runnable:
                   Thread thread = new Thread(new Calculador ())
                   thread.start();

Estados de un thread

Un thread tiene los siguientes estados:


New:  El objeto Thread se ha creado, pero el metodo start () no se ha invocado, en este punto no se                           considera vivo al thread.
Runnable :El metodo start () se ha invocado y es eligible para correr, pero el scheduler no lo ha                              seleccionado.
Running: El thread es seleccionado por el scheduler y ejecuta el metodo run ().
Waiting/blocked/sleeping: El thread está vivo, pero no es elegible para ejecutarse.
Dead: run () se ha completado.



Después de llamar al método start () la jvm hace lo siguiente:

         1. Un nuevo thread de ejecución se inicia.
         2. El thread se mueve del estado New al estado Runnable.
         3. Cuando el thread obtenga la oportunidad de ejecutarse, su metodo run() se ejecutará.



Un thread puede iniciarse sólo una vez, esto significa que el método start () no se puede llamar más de una vez. Si start () se llama más de una vez se lanzara una IllegalThreadStateException.

Executando multiples threads.

Un thread puede ser identificado por los siguientes atributos:

  • ID: identificador único para cada thread.
  • Name: Nombre del Tema.
  • Priority: Los threads pueden tener una prioridad entre uno y 10, donde uno es la prioridad más baja y 10 la más alta.
  • Status: Estado de un thread. Un thread puede encontrarse en uno de estos cinco estados: new, runnable, running, waiting, o terminado.


Cuando varios threads se ejecutan simultáneamente cada uno tiene al CPU de acuerdo al scheduler. No hay garantia cual thread comenzará o terminará primero. La única garantía es que cada thread se ejecutará hasta que complete su tarea.

Ejemplo:
                  public class Calculador extends Thread {
                        public void run() {
                             System.out.println(“Thread ejecutnadose:”  + this.getName());
                       }
                   }

                  Calculador primer =  new Calculador(“Primer”);
                  primer.start();
                  Calculador segundo =  new Calculador(“Segundo ”);
                  segundo.start();

No hay garantía de que el orden de los mensajes será:
         Thread ejecutandose: Primero
         Thread ejecutandose: Segundo 
La única garantía es que los dos mensajes aparecerán en la consola.


El método join () de la clase Thread suspende la ejecución del thread llamante hasta que el otro thread haya terminado.

                   Calculador primer =  new Calculador(“Primero”);
                   primer.start();
                   try {
                            primer.join():
                   } catch (InterruptedException e) {
                         e.printStackTrace();
                   }                 
                   Calculador segundo =  new Calculador(“Segundo ”);
                   segundo.start();

De esta manera la consola debe imprimir el mensaje en el siguiente orden:
         Thread ejecutandose: Primero
         Thread ejecutandose: Segundo


Ir a parte 2