1. Introducción
Es relativamente común que los programas Java agreguen un retraso o pausa en su funcionamiento. Esto puede ser útil para el ritmo de las tareas o para pausar la ejecución hasta que se complete otra tarea.
Este tutorial describirá dos formas de implementar retrasos en Java.
2. Un hilo Enfoque -Based
Cuando se ejecuta un programa Java, genera un proceso que se ejecuta en la máquina host. Este proceso contiene al menos un hilo, el hilo principal , en el que se ejecuta el programa. Además, Java permite el subproceso múltiple, lo que permite a las aplicaciones crear nuevos subprocesos que se ejecutan en paralelo o asincrónicamente con el subproceso principal.
2.1. Usando Thread.sleep
Una forma rápida y sucia de pausar en Java es decirle al hilo actual que se suspenda durante un período de tiempo específico. Esto se puede hacer usando Thread.sleep (milisegundos) :
try { Thread.sleep(secondsToSleep * 1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }
Es una buena práctica envolver el método de suspensión en un bloque try / catch en caso de que otro hilo interrumpa el hilo de dormir. En este caso, capturamos la InterruptedException e interrumpimos explícitamente el hilo actual, para que pueda ser capturado y manejado más tarde. Esto es más importante en un programa de subprocesos múltiples, pero sigue siendo una buena práctica en un programa de un solo subproceso en caso de que agreguemos otros subprocesos más adelante.
2.2. Usando TimeUnit.sleep
Para una mejor legibilidad, podemos usar TimeUnit.XXX.sleep (y) , donde XXX es la unidad de tiempo para dormir ( SEGUNDOS , MINUTOS , etc.), e y es el número de esa unidad para dormir. Esto usa Thread.sleep detrás de escena. Aquí hay un ejemplo de la sintaxis de TimeUnit :
try { TimeUnit.SECONDS.sleep(secondsToSleep); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }
Sin embargo, existen algunas desventajas al usar estos métodos basados en subprocesos :
- Los tiempos de reposo no son exactamente precisos, especialmente cuando se utilizan incrementos de tiempo más pequeños, como milisegundos y nanosegundos
- Cuando se usa dentro de los bucles, el sueño se desviará ligeramente entre las iteraciones del bucle debido a la ejecución de otro código, por lo que el tiempo de ejecución podría volverse impreciso después de muchas iteraciones.
3. Un enfoque basado en ExecutorService
Java proporciona la interfaz ScheduledExecutorService , que es una solución más sólida y precisa. Esta interfaz puede programar el código para que se ejecute una vez después de un retraso específico o en intervalos de tiempo fijos.
Para ejecutar un fragmento de código una vez después de un retraso, podemos usar el método de programación :
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.schedule(Classname::someTask, delayInSeconds, TimeUnit.SECONDS);
La parte Classname :: someTask es donde especificamos el método que se ejecutará después del retraso:
- someTask es el nombre del método que queremos ejecutar
- Classname es el nombre de la clase que contiene el método someTask
Para ejecutar una tarea a intervalos de tiempo fijos, podemos usar el método scheduleAtFixedRate :
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleAtFixedRate(Classname::someTask, 0, delayInSeconds, TimeUnit.SECONDS);
Esto llamará repetidamente al método someTask , haciendo una pausa para delayInSeconds entre cada llamada.
Además de permitir más opciones de tiempo, el método ScheduledExecutorService produce intervalos de tiempo más precisos, ya que evita problemas con la deriva.
4. Conclusión
En este artículo, discutimos dos métodos para crear retrasos en programas Java.
El código completo de este artículo se puede encontrar en Github. Este es un proyecto basado en Maven, por lo que debería ser fácil de importar y ejecutar como está.