Ejecutar una acción transcurrido un tiempo

publicado por: Anonymous

Necesito ejecutar una acción después de pasado un cierto tiempo una sola vez. He probado con lo siguiente:

Timeline contador = new Timeline(new KeyFrame(
        Duration.seconds(4),
        acción -> System.out.println("acción acontecida")));
    contador.play();
    }

parece funcionar bien pero, quiero saber si es la mejor manera o hay otra forma más recomendada.

solución

Para ejecutar tareas de forma repetitivas existen varias alternativas:

Un primer enfoque y muy sencillo de implementar es usar Timer y TimerTask, ambas del paquete java.util:

final Timer timer = new Timer();
TimerTask task = new TimerTask() {

    @Override
    public void run() {
        System.out.println("acción acontecida");
    }
};
timer.schedule(task, 0, 2000); // delay de 0 y se ejecuta cada 2 seg

Hay que tener algunas consideraciones muy importantes al trabajar con este enfoque: una excepción lanzada en TimerTask termina el hilo del Timer, sin posibilidad de poderlo reiniciar por lo cual tienes que hacer manejo de excepciones. Si lanzamos la tarea con schedule y ésta tarda más del tiempo estipulado (supongamos que tarda 3 seg más de los 2 seg establecidos) la siguiente tarea no se ejecutará hasta los 3+2 seg siguientes. Con scheduleAtFixedRate ocurre lo contrario; en lugar de ejecutarse a los 3+2 seg lo hará a los 1 seg para tratar de ajustarse (la tarea anterior consumió los 2 seg más 1 seg de la nueva tarea). Dependiendo de tus requerimientos debes configurarlo de una u otra forma.

Otro enfoque es utilizar ScheduledExecutorService una implementación de ExecutorService:

final Runnable tarea = () -> {
    System.out.println("acción acontecida");
};
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(tarea, 0, 2, TimeUnit.SECONDS); 

ScheduledExecutorService permite programar tareas para correr de forma periódica y/o con un retraso de inicio al igual que Timer pero es mucho más flexible y a diferencia de Timer no se detendrá si se genera una excepción en cualquiera de las tareas que maneja.

La siguiente entrada te orientará más sobre las principales diferencias y beneficios entre Timer y ExecutorService: https://stackoverflow.com/questions/409932/java-timer-vs-executorservice

Por último, Timeline es de propósito más específico y está orientado a la animación en JavaFX. Te recomiendo que uses uno de los dos enfoques anteriores.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *