Você está na página 1de 4

HILOS

Bueno, muchos me escucharon decir varias veces en la clase esa palabra. Y muchos se
habrán preguntado si el profe se quería poner a coser en el medio de la clase de Java.
Pues no. Cuando el profe habla de hilos, se refiere a procesos.
Un programa es un conjunto de procesos. Hasta ahora, nosotros siempre hicimos
programas que están formados por un solo proceso. O básicamente. Por ejemplo, el
garbage collector es un proceso aparte en nuestro programa. Se ejecuta como parte de
nuestro programa, pero mientras tanto, nuestro programa sigue haciendo lo suyo.

El uso de hilos sirve para que nuestro programa pueda hacer dos o más cosas a la vez.
Les voy a poner un ejemplo que considero simple:

Un servidor. ¿Qué pasa con un servidor? Bueno, cuando yo me conecto al servidor y le


pido datos, el servidor me los manda. Bárbaro, pero a un servidor se pueden conectar
muchos clientes. Y el servidor no los atiende uno por uno, sino que los atiende a todos
juntos. ¿Cómo sería eso posible en este mundo tan oscuro? ¿Habrá alguna solución
noble a este tipo de problemas que nos aqueja y atormenta día a día? Pues SÍ. La
solución se llama “hilos”.

Y bueno, la verdad es que es más difícil saber cuándo y cómo utilizar hilos dentro de un
problema en concreto, que el simple hecho de saber como se crea y usa un hilo
independientemente de algún problema. Y es por eso que les voy a hacer parecer que
este tema es muy fácil =P

Creando un hilo
Bueno, como ustedes saben, el profe les enseña la manera más PRO de hacer las cosas,
y esta no va a ser la excepción.

La posta es crear una clase, sobre la que vamos a creas a nuestro hilo (así como con las
interfaces gráficas nosotros creamos nuestras clases sobre la cuales creamos nuestros
formularios), y hacer que dicha clase:

1. Implemente Runnable
2. Herede de Thread

Dilema

Existe un dilema sobre si es mejor heredar de Thread o implementar Runnable. La posta


es que si heredamos de Thread nuestra clase no puede heredar de ninguna otra clase, por
lo cual suele ser más copado implementar de Runnable.
Implementación

Tanto al implementar Runnable como al heredar de Thread, tenemos que implementar


el método run() Este es el método que ejecuta el código del hilo.
Ya lo vamos a ver bien con el/los código/s (La indecisión entre singular y plural pone
en evidencia que todavía no hice ningún código). Este método, desde afuera del hilo, se
ejecutará llamando al método start(). Es fumón, pero lo van a ver.

Lo que necesitan saber sobre los hilos

Necesitan saber algunas cosas para entender lo que viene más adelante, así que el profe
PRO les va a decir lo que necesitan.

Primero, los hilos tienen una bandera de bloqueo. ¿Qué es esto? Bueno, una bandera
que dice que no se interrumpe la ejecución de ese hilo. El tema es que Java chequea
constantemente que un hilo está esperando a ejecutarse, y dependiendo de la prioridad
que tenga este (sí, los hielos tienen una prioridad) se deja para después (si tiene menos
prioridad que el que se ejecuta) o se interrumpe la ejecución del hilo actual y se atiende
al que lo solicita (si tiene mayor prioridad). El tema es cuando dos procesos tienen igual
prioridad. La máquina virtual, cuando más le guste, puede agarrar y decir “bueno, te
pongo a vos en espera y hago lo ejecuto al otro”. Eso no está mal, obviamente, porque
todos los hilos tienen que recibir atención, pero por ahí los dos hilos acceden a los
mismos datos y si el primer hilo, por ejemplo, no termina de escribir un dato, no puede
arrancar el segundo hilo y leer ese dato, porque sería una catástrofe para nuestro
programa. O sea, sí puede, y por ley de Morgan, si algo malo puede pasar, va a pasar.
Pero nosotros no queremos que eso pase. Entonces, para manejar eso con toda la
calidad, Java nos deja sincronizar bloques de código.

Sincornización

Cuando un bloque de código está sincronizado, ese bloque se ejecuta completo. Es


decir, no es que el hilo va a estar ejecutando ese código y a la mitad se va a pausar y va
a empezar a correr otro hilo, arruinándonos el programa, o peor aún, la vida misma.
La palabra clave synchronized nos soluciona este problema.

isAlive()

Este es un método que nos permite preguntarle a un hilo si todavía sigue vivo. Que siga
vivo no significa que en este momento esté en ejecución, ya que podría estar pausado,
esperando a que la máquina virtual le ceda un poquito de su atención. Que siga cico
significa que todavía no terminó de ejecutar todo su código.

sleep()

Ya hemos usado este método con anterioridad para pausar durante X milisegundos a un
programa. La posta es que este método pausa por ese tiempo al hilo desde el cual se
invoca. Es un método estático, por lo cual se llama como Thread.sleep().
join()

Este método hace que el hilo que lo ejecuta espere a que el hilo que lo llamó termine de
hacer lo suyo para seguir su ejecución. Es decir, cuando el otro hilo termina de ejecutar
su código, este hilo sigue ejecutando el suyo.

yield()

Este método pausa al hilo que lo llama para dar la posibilidad a otros hilos de
ejecutarse.

Nota: El método yield() Permite que otros hilos que están en estado de ejecución
continúen lo suyo. El método sleep() permite que otros hilos de menor prioridad
continúen su ejecución.

Los métodos wait() y join()

Bueno, como a nadie le gusta que lo molesten, a los hilos tampoco. Entonces que pasa,
no podemos dejar que los hilos anden mandando mensajes todo el tiempo y jodiéndose
entre ellos. Por eso, Java nos da dos métodos para que nuestra vida sea más simple. El
wait() y el join().

La onda es así:

En distintos métodos, se invocan a estos dos métodos, todo dentro del mismo objeto.
Cuando se llame al método que contiene el wait, el método se va a ejecutar hasta que
llegue al wait, y ahí va a parar. Y se va a quedar esperando hasta que alguien llame al
método de este objeto que invoque al join. En ese momento, el otro método continuará
ejecutando su código. “En ese momento” es una manera de decir, ya que si el hilo esta
en espera y hay otro con mas prioridad para ser ejecutado se va a ejecutar ese, ¿no?
Siempre pasan ese tipo de cosas, así que cuando hablamos de tiempos en hilos, no se
habla taaaaan literalmente.

Un ejemplito:

class Euforico{
boolean terminasteDeTomarLaRedBull = false;

public synchronized void calmateUnPoco(){


while(!terminasteDeTomarLaRedBull){
try{ wait();
}catch(InterruptedException e){
//no hago nada =P
}
}
System.out.println(“Ok ok, ya me calmé”);
}
public synchronized void tomatelaGuachin(){
notify();
terminasteDeTomarLaRedBull = true;
}
}//este es un código feliz.

Bueno, ¿qué pasa con este código? Cuando algún objeto llame al método
calmateUnPoco() debería imprimir que ya se calmó, pero para hacer eso, primero
necesita terminar de tomar su red bull. Entonces, cuando otro objeto ejecute
tomatelaGuachin(), este objeto va a “despertarse” y va a poner su bandera true (o sea
que se tomó toda la red bull) y ahí va a seguir ejecutando el método calmateUnPoco().
Como ahora terminasteDeTomarLaRedBull vale true, va a salir del while y va a seguir
haciendo lo suyo, esto es, imprimir que ya se calmó.
Como deben haber notado, los dos métodos están sincronizados. Esto es porque ni el
wait ni el join pueden ir en bloques de código que no estén sincronizados.

En la clase completamos el código. ¿va?

Você também pode gostar