style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Opinion / Interrupts de Threads

Quería probar Interrupts del ejemplo http://download.oracle.com/javase/tutorial/essential/concurrency/interru..., así que decidí emular el clásico Control-C usando Thread.interrupt(). La intención de ponerlo es para tener sus observaciones, opiniones, etc. También me gustaría saber más sobre como usar Interrupts, donde usarlo o todos los tips que se les ocurran.

Conociéndome, cuando tenga que hacer algo así usare este método y no se si es lo conveniente o correcto.

Por ejemplo: Cuando una aplicación procesa miles de registros de una base de datos y los arroja a la terminal, de repente vemos el dato que deseamos (por más rápido que se imprima en pantalla heee) y guala con un Control-C terminamos el proceso. Solo que en ves de miles de registros uso caritas, y en ves de Control-C comparo un String.

public class SleepMessage implements Runnable {

    private String state;
    private String states[] = {"Strart", ":)", ":D", ":P", ":|", ":O", ":S", ":?", "END"};

    public void run() {
        for (String stateNow : states) {
            state = stateNow;
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                System.err.println("Ctrl-C!!!");
                return;
            }
            System.out.println(stateNow);
        }
    }

    public String getState() {
        return state;
    }
}

public class Main {

    public static void main(String... args) {
        SleepMessage sleepMessage = new SleepMessage();
        Thread thread = new Thread(sleepMessage);
        thread.start();

        while (thread.isAlive()) {
            String state =
                    sleepMessage.getState() == null
                    ? "NO_STATE" : sleepMessage.getState();
            //Presionan ctrl-c para terminar el proceso (digo hilo... :P)
            if (state.equals(":|") ? true : false) {
                thread.interrupt();
            }
        }
    }
}

Bueno pues muchisimas gracias por el tiempo a todos... bye.
EDIT: La definición de la clase y atributos no concuerda con el propósito del ejemplo, algo que no interfiere pero incomoda : ) sorry...

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Ese parecería un escenario

Ese parecería un escenario bueno, detener el hilo cuando se desea.

Generalmente cuando se quiere hacer que un hilo haga algo por determinado tiempo se pone una condición ( como ayer que estabas buscando que fuera el número 2 ) Pero en este escenario donde no sabes cuando hay que parar, usar Interrupt parece adecuado.

Quizá el único inconveniente es que tienes que tener una referencia al hilo que deseas detener, otro inconveniente ( este mucho menos importante ) es que puedes ignorar la señal de detenerse, digo menos importante, porque se supone que tu sabes dentro de tu programa si un hilo ha de detenerse o no.

El el documento que mencionas, también está listada la opción:

if( Thread.isInterrupted() ) {
   ...
}

Que es otra forma de ver si ha de detenerse la ejecución o no del thread.

Cuando se habla de concurrencia en Java, este libro surge reiteradamente:

http://www.javaconcurrencyinpractice.com/

Si lo compras, luego me lo prestas para ojearlo.

Doug Lea, uno de los autores fue quién escribió gran parte del paquete java.util.concurrent.

También esta este artículo que algún día leeré:Concurrent progamming with J2SE 5.0

Saludos

Imagen de rodrigo salado anaya

Vientos Oscar, gracias por

Vientos Oscar, gracias por los tips :D. Si no lo deje con el if (Thread.interrupted()) { por mera cuestión visual...

public void run() {
        for (String stateNow : states) {
            state = stateNow;
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                System.err.println(ex);
            }
            if (Thread.interrupted()) {
                System.err.println("Ctrl-C!!!");
                return;
            }
            System.out.println(stateNow);
        }
    }

Y esto nos arroja:

Strart
:)
:D
:P
java.lang.InterruptedException: sleep interrupted
Ctrl-C!!!

Pero me llama mucho la atención ( casi todo jejeje) lo que usa @Ezamudio en este articulo http://www.javamexico.org/blogs/ezamudio/ejemplo_de_ataque_de_negacion_d... y que aparece en el que manadas te Atomic variables: The java.util.concurrent.atomic package...

Me la voy a llevar tranquila si no me engolosino :D.

No te entendí a que te

No te entendí a que te refieres con eso de manadas de Atomic variables Te sale eso cuando ejecutas o que?

Imagen de rodrigo salado anaya

Ok. :S

Oscar lo siento :S. Las prisas como siempre. Pues que me interesa mucho entender el tema de como usar las Atomic variables, como en estas ligas mencionan y entre otras más claro: http://www.vogella.de/articles/JavaConcurrency/article.html#memorymodel_... http://www.ibm.com/developerworks/java/library/j-jtp11234/

Mentiría si te digo que se para que se usan sólidamente y solo me falta aprender a usarlas jejeje, pero bueno me tomare mi tiempo para ir de lo básico a lo más complejo y echare un par de preguntas a la comunidad. Vale pues suerte : ).

Tampoco es muy

Tampoco es muy complejo.

Tienes un objeto. Este objeto tiene un atributo "contador" ( un entero por ejemplo ). Si el atributo de este objeto es accedido por dos o más hilos, se requiere sincronizar el acceso para que tengas resultados consistentes. Ejemplo:

class Objeto {
   int contador;
}

Si el thread 1 y el thread 2 tienen acceso a ese objeto, alguno de los dos podría hacer lo siguiente:

o.contador++; // olvidandonos por lo pronto de los getters y demás cosas...

El problema está en que el otro thread, puede "ver" el valor incorrecto, puede ser que vea el valor antes del incremento o después.

Para solucionarlo se puede usar el acceso sincronizado ( donde solo un thread puede modificarlo a la vez )

synchronized( o ) {
   o.contador++;
}

La desventaja es que si tienes digamos 100 threads y todos quieren hacer esto, todos se van a embotellar aquí, queriendo ganar el lock del objeto "o"

O... se puede usar un AtomicInteger

class Object {
   AtomicInteger contador = new AtomicInteger();
}
// en algun thread....
   o.contador.getAndIncrement();

La diferencia es que así se puede acceder al atributo sin necesidad de sincronizar el acceso ( evitando cuellos de botella por ejemplo ) y al mismo tiempo garantizando que el incremento sea "atomico" ( o sea de un solo jalón pues )

Lo mejor ( más sencillo ) sería por supuesto, que este valor no estuviera compartido entre tantos threads y que ellos trabajaran de forma independiente, pero a veces, esto no es posible.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">