Skip to content

6 Dormir

Dormir un hilo

Algunas veces será interesante suspender la ejecución de un hilo durante un determinado periodo de tiempo, como por ejemplo en el caso de un hilo que se dedique a comprobar el estado de un sensor cada minuto. Una vez realizada la comprobación, el hilo debe pasar al estado de dormido durante aproximadamente un minuto, liberando cualquier recurso que estuviera utilizando, incluyendo el procesador. Una vez pasado el minuto, el hilo será despertado por el sistema y estará listo para continuar con su ejecución cuando el sistema lo determine.

Para dormir un hilo podremos usar el método sleep(milliseconds) de la clase Thread, que recibe un entero en el que indicamos el número de milisegundos que queremos que el hilo suspenda su ejecución. Cuando concluye el tiempo indicado, el hilo continúa su ejecución en la instrucción siguiente a sleep(), cuando el sistema así lo determine.

Cuando se llama al método sleep(), el hilo libera la CPU y detiene su ejecución el tiempo especificado, durante el cual la CPU puede estar ejecutando otras tareas.

Uso de sleep()

Nosotros usaremos sleep() para simular tareas que tardan un determinado tiempo en ejecutarse

En todo caso, debemos tener en cuenta que, no tenemos garantía de que la cantidad de tiempo que pasamos al método sleep() sea exactamente el tiempo que esté durmiendo el hilo correspondiente, ya que dependerá de la funcionalidad proporcionada por el sistema operativo.

Existe otra posibilidad para dormir un hilo, que consiste en usar el método sleep() de algún elemento de la enumeración TimeUnit, definida en el paquete java.util.concurrent, que recibirá el tiempo de suspensión en la unidad correspondiente a dicha enumeración, en vez de en milisegundos. Por ejemplo, TimeUnit.SECONDS.sleep(1) duerme el hilo correspondiente durante 1 segundo.

Si se trata de echar a dormir un hilo que ha sido marcado como interrupción, o si un hilo está durmiendo y se marca como interrumpido, se lanza inmediatamente en el hilo la excepción InterruptedException, sin esperar a que concluya el tiempo durante el cual el hilo debe estar dormido.

En nuestros proyectos usaremos la técnica de dormir un hilo para simular el tiempo que se tarda en realizar una determinada tarea.

Warning

No se recomienda el uso del método yield()

La clase Thread posee otro método que permite liberar la CPU para que ejecute otra tarea. Se trata del método yield() (ceder), aunque la JVM no garantiza que dicha cesión se lleve a cabo siempre, por lo que no se recomienda su uso, y sólo puede utilizarse cuando estemos depurando nuestro código.

Proyecto Clock

En este proyecto desarrollaremos un programa que cree un hilo que muestre por pantalla cada segundo la hora actual con horas, minutos y segundos. Haremos uso del método sleep() para dormir el hilo durante un segundo entre muestra y muestra. Transcurridos unos segundos el hilo principal interrumpirá al hilo reloj.

import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new SecondsHand(), "Seconds hand");
        thread.start();
        TimeUnit.SECONDS.sleep(5);
        thread.interrupt();
    }

}
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

public class SecondsHand implements Runnable {

    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println(LocalDateTime.now().format(dateTimeFormatter));
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                System.out.println("I've been interrupted while sleeping");
                return;
            }
        }
        System.out.println("I've been interrupted");
    }

}

Si ejecutamos el programa veremos que se va mostrando la hora segundo a segundo hasta que pasan 5 segundos, momento en el que el hilo principal interrumpe al hilo secundario.