Anuncios

Bienvenidos sean a este post, en el post de hoy hablaremos sobre la posibilidad que nos da el nucleo de Java para poder controlar a todos los procesos creados en nuestro programa de multiprocesos (multithreading).

Anuncios

Esto significa que nosotros podemos desarrollar un programa de este estilo que podemos pausar, retomar o terminar dependiendo de nuestros requerimientos, disponemos de varios metodos estaticos para poder controlar a estos objetos de tipo Thread, veamos un listado de algunos de ellos:

  • public void suspend(), este metodo pasa al proceso (thread) en estado suspendido y puede ser retomado por medio del metodo resume()
  • public void stop(), este metodo detiene un proceso completamente
  • public void resume(), este metodo retoma un proceso que fue suspendido por el metodo suspend()
  • public void wait(), hace al proceso actual que espera hasta que otro proceso invoque a notify()
  • public void notify(), despierta a un solo proceso que esta esperando al monitor de objetos
Nota: En las ultimas versiones de Java los metodos suspend(), resume() y stop() han sido descartadas por lo que pueden necesitar algunos alternativos.
Anuncios

Al margen de la nota veamos un ejemplo a continuacion para entender mejor este concepto:

TestThread.java

class RunnableDemo implements Runnable
{
        public Thread t;
        private String nombreProceso;
        boolean suspendido = false;

        RunnableDemo (String nombre)
        {
                nombreProceso = nombre;
                System.out.println("Creando " + nombreProceso);
        }

        public void run()
        {
                System.out.println("Ejecutando " + nombreProceso);
                try
                {
                        for(int i = 10; i > 0; i--)
                        {
                                System.out.println("Thread: "
                                        + nombreProceso + ", " + i);
                                Thread.sleep(300);
                                synchronized(this)
                                {
                                        while(suspendido)
                                                wait();
                                }
                        }
                }
                catch (InterruptedException e)
                {
                        System.out.println("Thread " + nombreProceso
                                        + " interrumpido.");
                }
        }

        public void start()
        {
                System.out.println("Iniciando " + nombreProceso);
                if (t == null)
                {
                        t = new Thread(this, nombreProceso);
                        t.start();
                }
        }

        void suspend()
        {
                suspendido = true;
        }

        synchronized void resume()
        {
                suspendido = false;
                notify();
        }
}

public class TestThread
{
        public static void main(String[] args)
        {
                RunnableDemo R1 = new RunnableDemo("Thread-1");
                R1.start();
                RunnableDemo R2 = new RunnableDemo("Thread-2");
                R2.start();

                try
                {
                        Thread.sleep(1000);
                        R1.suspend();
                        System.out.println("Suspendiendo primer thread");
                        Thread.sleep(1000);
                        R1.resume();
                        System.out.println("Retomando primer thread");

                        R2.suspend();
                        System.out.println("Suspendiendo segundo thread");
                        Thread.sleep(1000);
                        R2.resume();
                        System.out.println("Retomando segundo thread");
                }
                catch (InterruptedException e)
                {
                        System.out.println("Thread principal interrumpido");
                }
                try
                {
                        System.out.println("Esperando los threads para "
                                                + "terminar.");
                        R1.t.join();
                        R2.t.join();
                }
                catch (InterruptedException e)
                {
                        System.out.println("Thread principal interrumpido");
                }
                System.out.println("Saliendo del thread principal.");
        }
}
Anuncios

En este ejemplo primero crearemos una clase llamada RunnableDemo la cual implementara a la clase Runnable, luego crearemos tres variables, una de tipo Thread llamada t, otra de tipo String llamada nombreProceso y por ultimo una de tipo boolean llamada suspendido la cual setearemos como false, despues tenemos nuestro constructor donde le daremos la posibilidad de informar un atributo llamado nombre, a este atributo lo asignaremos a la variable nombreProceso y luego mostraremos un mensaje, nuestro siguiente metodo es run(), uno de los que debemos sobreescribir para poder implemetar la clase Runnable, donde primero mostrara el nombre del proceso por medio de nombreProceso, luego tendremos un bloque try/catch donde usaremos un bucle for para hacer un conteo de 10 a 0 donde mostraremos un mensaje relacionado a nuestro proceso, lo pausaremos 300 milisegundos para despues tener un bloque synchronized donde sincronizara al proceso actual y por medio de un while chequeara si suspendido es igual a true, y en caso de ser verdadero llamara al wait(), despues tenemos el catch donde nos mostrara un mensaje de error ante una excepcion en este proceso.

Anuncios

Nuestro siguiente metodo es start(), el segundo metodo necesario para poder implementar a Runnable, donde mostraremos un mensaje y luego chequearemos si t es igual a null y en caso de ser verdadero crearemos un nuevo proceso y lo asignaremos a t, donde le diremos el contexto (this) y luego le pasaremos un nombre gracias a nombreProceso, y por ultimo lo iniciaremos, el siguiente metodo es suspend() donde setearemos a suspendido como true (verdadero), para finalmente definir a resume() que en este caso utilizaremos a synchronized y setearemos a suspendido como false y llamaremos a notify() para anular el wait().

Anuncios

Despues tenemos el main() donde crearemos dos objetos de tipo RunnableDemo los cuales seran R1 y R2 a los cuales llamaremos Thread-1 y Thread-2 respectivamente, despues en el bloque try/catch detendremos al proceso por un segundo, despues suspenderemos al objeto R1, mostraremos un mensaje notificando esta suspension, detendremos el proceso nuevamente durante un segundo, para luego retomarlo con resume(), y mostramos la notificacion de esta accion, luego suspendemos al objeto R2, mostramos un mensaje relacionado a esto, detenemos el proceso durante un segundo, lo volvemos a retomar y mostramos el mensaje sobre esta accion, el catch se encarga de mostrar una notificacion si el proceso fuese interrumpido, despues vendra otro bloque try/catch donde mostraremos un mensaje para esperar a que terminen los procesos, despues a los objetos R1 y R2 lo instanciaremos a t y a join(), el bloque catch hace exactamente lo mismo a los anteriores y por ultimo mostramos un mensaje cuando salimos del proceso principal, si lo compilamos y probamos obtendremos el siguiente resultado

Anuncios

Observen como se llamo correctamente a las posibilidades de poder interrumpir y retomar nuestros procesos de forma correcta, permitiendo poder seguir corriendo un proceso mientras el otro espera retomar su accion .

Anuncios

En resumen, hoy hemos visto como se puede controlar los procesos que se crean, los metodos disponibles, aunque pueden ser obsoletos estos se siguen usando y hemos visto un ejemplo donde se implementan correctamente, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00