HOWTO · Java
Como Atrasar Poucos Segundos em Java
Saiba quando usar Thread.sleep() para uma pausa bloqueante e quando agendar trabalho atrasado ou repetitivo em Java.
Nesta página
Para uma pausa simples, use Thread.sleep(); ele suspende a thread atual pela duração solicitada. Se o trabalho precisar começar mais tarde ou se repetir enquanto a thread que fez a chamada continua disponível, use um ScheduledExecutorService. Os exemplos a seguir mostram as duas opções, como lidar com interrupções e como encerrar tarefas agendadas.
Pausar a execução pertence ao grupo de utilitários do Tutorial de Java, com as outras receitas quotidianas de datas, números aleatórios e consola.
Use Thread.sleep() para uma pausa bloqueante simples
Thread.sleep() recebe uma duração em milissegundos e pausa a thread que o chamou. Este programa independente espera um segundo antes de exibir uma mensagem. O método main declara InterruptedException, portanto a interrupção é repassada ao chamador em vez de ser ignorada silenciosamente.
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread.sleep(1000);
System.out.println("One second has passed.");
}
}
Em um método que não pode repassar InterruptedException ao chamador, capture a exceção e restaure o status de interrupção com Thread.currentThread().interrupt(). Assim, o código de nível superior pode detectar a solicitação de cancelamento e reagir conforme a política da aplicação. A pausa suspende somente a thread atual; ela não pausa as outras threads do processo.
Use TimeUnit.sleep() para indicar a unidade do intervalo
TimeUnit.SECONDS.sleep(2) expressa diretamente uma pausa de dois segundos. Ainda assim, ele bloqueia a thread que fez a chamada e pode ser interrompido; portanto, aplique a mesma política de interrupção usada com Thread.sleep().
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("Two seconds have passed.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Pause interrupted.");
}
}
}
Escolha essa forma quando indicar a unidade tornar a duração mais fácil de entender. TimeUnit.sleep() é uma maneira legível de expressar uma espera temporizada, mas não mantém a thread atual disponível para outras tarefas durante a pausa.
Agende uma tarefa recorrente com ScheduledExecutorService
Um ScheduledExecutorService executa um Runnable após um intervalo ou em intervalos regulares, enquanto a thread que fez a chamada continua disponível. scheduleAtFixedRate() recebe a tarefa, um atraso inicial, um período e uma TimeUnit. O executor chama o método run() da tarefa; é em run() que o trabalho é definido, e esse método não agenda a si próprio.
Este programa inicia uma tarefa após um segundo e solicita novas execuções a cada segundo. Outra ação agendada cancela a tarefa recorrente e encerra o executor após cinco segundos. Como o agendamento depende da disponibilidade de recursos durante a execução, a quantidade e o momento das linhas exibidas podem variar.
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> task = executor.scheduleAtFixedRate(
() -> System.out.println("Task running"), 1, 1, TimeUnit.SECONDS);
executor.schedule(() -> {
task.cancel(false);
executor.shutdown();
}, 5, TimeUnit.SECONDS);
}
}
Guarde o ScheduledFuture retornado se talvez seja necessário cancelar a tarefa recorrente. Encerre um executor quando a aplicação não precisar mais dele; caso contrário, sua thread de trabalho poderá manter o processo em execução. Para uma única ação com atraso, use schedule() em vez de um agendamento recorrente.
Use uma referência de método com ScheduledExecutorService
Quando um método existente sem argumentos representa a tarefa, uma referência de método pode fornecê-lo como Runnable. Este programa agenda uma chamada para daqui a dois segundos e, em seguida, encerra o executor. O encerramento impede o envio de novas tarefas, mas permite que a tarefa já enfileirada termine.
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.schedule(Main::executeTask, 2, TimeUnit.SECONDS);
executor.shutdown();
}
private static void executeTask() {
System.out.println("Task running");
}
}
Use um método de pausa para um intervalo curto quando for desejável parar a thread atual. Escolha um executor agendado quando outras tarefas precisarem continuar ou quando uma tarefa tiver de começar mais tarde ou se repetir. A pausa bloqueia a thread que fez a chamada e não exige encerrar um executor; o trabalho agendado mantém essa thread disponível, mas o executor deve ser encerrado e as tarefas recorrentes canceladas quando não forem mais necessárias.