Monday, May 6, 2013

Concurrencia en Java Parte 2

Esta es la segunda parte de mi post original Concurrencia en java parte-1


Prioridades en Threads

Todos los threads tienen un valor de prioridad entre 1 y 10. En la mayoría de los casos, el thread en ejecución tendrá la misma prioridad que la máxima prioridad de los threads del pool.
Si algunos threads tienen la misma prioridad, es el scheduler (programador) el que decide que thread ejecuta.

Por defecto, un thread obtiene su prioridad de el thread de ejecución que lo creó, pero se puede cambiar a través del método setPriority(int), este método puede lanzar una IllegalArgumentException si el valor se establece que no está entre 1 y 10.

El método estático yield() de la clase Thread indica a la JVM que el thread en ejecución puede dejar el CPU e ir a estado runnable, permitiendo a otros threads con la misma o mayor prioridad ejecutarse. La JVM no garantiza este comportamiento.

Thread durmiendo


El método estático sleep(long) de la clase Thread hace que el que el thread en ejecución se detenga por lo menos la duración especificada en milisegundos indicada por el parámetro.
Al terminar el tiempo de dormir y la JVM asigna tiempo de CPU al thread dormido, y continúa en la instrucción siguiente a la llamada del método sleep ().

Ejemplo:

           public class Calculador extends Thread {
          public void run() {
      System.out.println(“Thread en ejecucion:” + this.getName() + “, comenzado en:” + Calendar.getInstance().getTimeInMillis());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
      System.out.println(“Thread en ejecucion:” + this.getName() + “, terminado :” + Calendar.getInstance().getTimeInMillis());
         }         
    }
Los mensajes la consola deben tener una diferencia de tiempo de por lo menos de 5 segundos.

Excepciones

La excepción InterruptedException es lanzada por algunos métodos relacionadas con la API de concurrencia de java, para indicar que el thread ha sido interrumpido.

Si no sabes que es una excepción de tipo “checked” o “unchecked” , ve a este link:

Las excepciones de tipo “checked” lanzadas dentro del método run() de un objeto thread se deben atrapar y tratarse, porque el método run() de la interfaz Runnable no declara ninguna cláusula throws.

Las excepciones de tipo “unchecked” lanzadas dentro del método run() de un objeto thread no requieren atraparse y la mayoría de las veces hacen que el programa termine. Para las excepciones de tipo “unchecked” Java proporciona una forma de detectar y tratar las excepciones en un objeto thread para evitar que el programa finalice.

Los pasos para implementar esto son:
  1. Cree una clase que implemente Thread.UncaughtExceptionHandler.
  2. Establecer el manejador de excepciones al objeto thread.



Ejemplo:

          public class ManejadorException implements UncaughtExceptionHandler {

               public void uncaughtException(Thread t, Throwable e) {
                    System.out.println("Una excepcion ha sido atrapada");
                    e.printStackTrace(System.out);
                    System.out.println("Thread status: " + t.getState());
               }
          }



          public class Calculador implements Thread {
               public void run() {
                    throw new RuntimeException(“Excepcion lanzada”);
               }
          }

          ............
          Calculador calculador = new Calculador();
          calculador.setUncaughtExceptionHandler(new ManejadorException());
          calculador.start();

          ............

La consola debe imprimir los mensajes del manejador de excepciones.

La clase Thread tiene otro método para controlar las excepciones de tipo “unchecked”, es el metodo estatico setDefaultUncaughtExceptionHandler(), este método establece un manejador de excepciones para todos los threads en una aplicación.


Fabrica de threads.

El patrón de diseño de fábrica es un patrón creacional cuya misión es crear objetos. Este patrón provee algunas ventajas como la facilidad de cambiar la forma en que se crean objetos, limitar la creación de los recursos, y así sucesivamente.

La interfaz java.util.concurrent.ThreadFactory proporciona una forma de implementar una fábrica objetos de tipo Thread. Sólo tiene el método newThread() que recibe un objeto Runnable como  parámetro y devuelve un objeto Thread.

Ejemplo:

         public class Fabrica implements ThreadFactory {
              private int contador = 1;

              public Thread newThread(Runnable r) {
                   Thread t=new Thread(r, "Thread: " +contador);
                   contador++;
                   return t;
              }
         }

         public class Calculador implements Runnable {
               public void run() {
                    .......
               }
         }

         ....
         Fabrica fabrica=new Fabrica();
         Calculador calculador = new Calculador ();
         for (int i=0; i<10; i++){
                Thread thread=fabrica.newThread(calculador);
                thread.start();
          }
          .....

Después del ciclo for 10 objetos thread han sido creados e inicializados.


Ir a parte 3


2 comments:

  1. Seria bueno que comentes tmb sobre las diversas formas de sincronizar los hilos ya que a veces hay un comportamiento inesperado a la ejecucion.

    Buen articulo, saludos.

    ReplyDelete
  2. Si eso lo tengo planeado poner mas delante, gracias por el consejo.

    ReplyDelete