Threads de Control

Los mtodos get() y put() del objeto CubbyHole hacen uso de los mtodos notify() y wait() para coordinar la obtencin y puesta de valores dentro de CubbyHole. Los mtodos notify() y wait() son miembros de la clase java.lang.Object.

Nota:

Los mtodos notify() y wait() pueden ser invocados slo desde dentro de un mtodo sincronizado o dentro de un bloque o una sentencia sincronizada.

Investiguemos el uso del mtodo notify() en CubbyHole mirando el mtodo get().

.El mtodo notify()

El mtodo get() llama al mtodo notify() como lo ltimo que hace (junto retornar). El mtodo notify() elige un thread que est esperando el monitor poseido por el thread actual y lo despierta. Normalmente, el thread que espera capturar el monitor y proceder.

El caso del ejemplo Productor/Consumidor, el thread Consumidor llama al mtodo get(), por lo que el mtodo Consumidor posee el monitor de CubbyHole durante la ejecucin del mtodo get(). Al final del mtodo get(), la llamada al mtodo notify() despierta al thread Productor que obtiene el monitor de CubbyHole y procede.

public synchronized int get() {
    while (available == false) {
        try {
            wait();
        } catch (InterruptedException e) {
        }
    }
    available = false;
    notify();           // lo notifica al Productor
    return contents;
}

Si existen varios threads esperando por un monitor, el sistema de ejecucin Java elige uno de esos threads, sin ningn compromiso ni garanta sobre el thread que ser eligido.

El mtodo put() trabaja de un forma similar a get(), despertanto al thread consumidor que est esperando que el Productor libere el monitor.

La clase Object tiene otro mtodo --notifyAll()-- que despierta todos lo threads que estn esperando al mismo monitor. En esta Situacin, los threads despertados compiten por el monitor. Uno de ellos obtiene el monitor y los otros vuelven a esperar.

.El mtodo wait()

El mtodo wait() hace que el thread actual espere (posiblemente para siempre) hasta que otro thread se lo notifique o a que cambie un condicin. Se utiliza el mtodo wait() en conjuncin con el mtodo notify() para coordinar la actividad de varios threads que utilizan los mismos recursos.

El mtodo get() contiene una sentencia while que hace un bucle hasta que available se convierte en true. Si available es false -- el Productor todava no ha producido un nuevo nmero y el consumidor debe esperar -- el mtodo get() llama a wait().

El bucle while contiene la llamada a wait(). El mtodo wait() espera indefinidamente hasta que llegue una notificacin del thread Productor. Cuando el mtodo put() llama a notify(), el Consumidor despierta del estado de espera y contina con el bucle. Presumiblemente, el Productor ya ha generado un nuevo nmero y el mtodo get() cae al final del bucle y procede. Si el Productor no ha generado un nuevo nmero, get() vuelve al principio del bucle y continua espeando hasta que el Productor genere un nuevo nmero y llame a notify().

public synchronized int get() {
    while (available == false) {
        try {
            wait();          // espera una llamada a notify() desde el Productor
        } catch (InterruptedException e) {
        }
    }
    available = false;
    notify();
    return contents;
}

El mtodo put() trabaja de un forma similar, esperando a que el thread Consumidor consuma el valor actual antes de permitir que el Productor genere uno nuevo.

Junto a la versin utilizada en el ejemplo de Productor/Consumidor, que espera indefinidamente una notificacin, la clase Object contiene otras dos versiones del mtodo wait().

wait(long timeout)
Espera una notificacin o hasta que haya pasado el tiempo de espera --timeout se mide en milisegundos.
wait(long timeout, int nanos)
Espera una notificacin o hasta que hayan pasado timeout milisegundos mas nanos nanosegundos.

.Los Monitores y los Mtodos notify() y wait()

Habras observado un problema potencial en los mtodos put() y get() de CubbyHole. Al principio del mtodo get(), si el valor de CubbyHole no est disponible (esto es, el Productor no ha generado un nuevo nmero desde la ltima vez que el Consumidor lo consumi), luego el Consumidor espera a que el Productor ponga un nuevo nmero en CubbyHole. Aqu est la cuestin -- cmo puede el Productor poner un nuevo valor dentro de CubbyHole si el Consumidor tiene el monitor? (El Consumidor posee el monitor de CubbyHole porque est dentro del mtodo get() que est sincronizado).

Similarmente, al principio del mtodo put(), si todava no se ha consumido el valor, el Productor espera a que el Consumidor consuma el valor del CubbyHole. Y de nuevo llegamos a la cuestin -- Cmo puede el consumidor obtener el valor de CubbyHole, si el Productor posee el monitor? (El productor posee el monitor de CubbyHole porque est dentro dentro del mtodo put() que est sincronizado).

Bien, los diseadores del lenguaje Java tambin pensaron en esto. Cuando el thread entra en el mtodo wait(), lo que sucede al principio de los mtodos put() y get, el monitor es liberado automticamente, y cuando el thread sale del mtodo wait(), se adquiere de nuevo el monitor. Esto le da una oportunidad al objeto que est esperando de adquirir el monitor y, dependiendo, de quin est esperando, consume el valor de CubbyHole o produce un nuevo valor para el CubbyHole.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

HAY 1 COMENTARIOS
  • Anónimo dijo:

    Hola muy buena la explicaion sobre threads, pero tuvieras algun ejemplo pero aplicado a action sript 2 o php

Conéctate o Regístrate para dejar tu comentario.