Como faço para atrasar em Java?

343

Estou tentando fazer algo em Java e preciso de algo para esperar / atrasar por alguns segundos em um loop while.

while (true) {
    if (i == 3) {
        i = 0;
    }

    ceva[i].setSelected(true);

    // I need to wait here

    ceva[i].setSelected(false);

    // I need to wait here

    i++;
}

Quero criar um sequenciador de etapas e sou novo em Java. Alguma sugestão?

ardb
fonte
19
Use Thread.Sleep().
minúsculo
2
Considere usar um timer
PeterMmm
2
Qual é o propósito de esperar? Você está esperando por um determinado evento? Certifique-se de entender o que sleep () método faz
artdanil
@ Minúsculo, não é seguro.
Yousha Aleayoub
12
Na verdade é Thread.sleep(<milisecondsToSleep>). O snão deve ser capitalizado.
Benjamin

Respostas:

678

Se você deseja fazer uma pausa, use java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Dormir por um segundo ou

TimeUnit.MINUTES.sleep(1);

Dormir por um minuto.

Como se trata de um loop, isso apresenta um problema inerente - desvio. Toda vez que você executa o código e, em seguida, dorme, estará um pouco à deriva, digamos, a cada segundo. Se este for um problema, não use sleep.

Além disso, sleepnão é muito flexível quando se trata de controle.

Para executar uma tarefa a cada segundo ou com um atraso de um segundo, recomendo vivamente um ScheduledExecutorServicee ou scheduleAtFixedRateou scheduleWithFixedDelay.

Por exemplo, para executar o método a myTaskcada segundo (Java 8):

public static void main(String[] args) {
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(App::myTask, 0, 1, TimeUnit.SECONDS);
}

private static void myTask() {
    System.out.println("Running");
}

E no Java 7:

public static void main(String[] args) {
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            myTask();
        }
    }, 0, 1, TimeUnit.SECONDS);
}

private static void myTask() {
    System.out.println("Running");
}
Boris, a Aranha
fonte
11
@ Matthew Moisen Não consegui executar este exemplo do Java 8. O que é App :: exatamente? Ao alterar myTask () para um lambda executável, ele funciona: Runnable myTask = () -> {...};
precisa saber é o seguinte
2
É uma referência de método @comfytoday - sugiro começar com a documentação .
Boris the Spider
TimeUnit.SECONDS.wait(1)está lançando IllegalMonitorStateExceptionno Java 8.1 build 31 no Windows 6.3. Em vez disso, sou capaz de usar Thread.sleep(1000)sem uma tentativa / captura.
31519 John Meyer
11
No Java 8, em java.util.concurrent.TimeUnit você obtém Unhandled exception: java.lang.InterruptedExecutionpara osleep(1)
Shai Alon
11
Você deve cercar o TimeUnit.SECONDS.sleep(1);comtry catch
Shai Alon
148

Use Thread.sleep(1000);

1000 é o número de milissegundos que o programa fará uma pausa.

try
{
    Thread.sleep(1000);
}
catch(InterruptedException ex)
{
    Thread.currentThread().interrupt();
}
Anju Aravind
fonte
5
Não se esqueça de registrar a InterruptedException ou você nunca saberá que esse segmento foi interrompido.
m0skit0
12
Estou curioso para saber o que é o Thread.currentThread (). Interrupt (); faz aqui.
Brent212
11
veja: "Por que precisamos interromper o thread novamente?" aqui: javaspecialists.eu/archive/Issue056.html
Tristan
5

usa isto:

public static void wait(int ms){
        try
        {
            Thread.sleep(ms);
        }
        catch(InterruptedException ex)
        {
            Thread.currentThread().interrupt();
        }
    }

então você pode chamar esse método em qualquer lugar como:

        wait(1000);
Hecanet
fonte
3

Usando TimeUnit.SECONDS.sleep(1);ou Thread.sleep(1000);É uma maneira aceitável de fazer isso. Nos dois casos, você precisa capturar o InterruptedExceptionque torna seu código Bulky. Existe uma biblioteca java de código aberto chamada MgntUtils (escrita por mim) que fornece um utilitário que já lida com o InterruptedExceptioninterior. Portanto, seu código incluiria apenas uma linha:

TimeUtils.sleepFor(1, TimeUnit.SECONDS);

Veja o javadoc aqui . Você pode acessar a biblioteca do Maven Central ou do Github . O artigo explicando sobre a biblioteca pode ser encontrado aqui

Michael Gantman
fonte
2
Usar NÃOcatch (InterruptedException e) { /* empty */ } é uma solução sensata aqui. No mínimo, você deve fornecer algumas informações de log. Para mais informações sobre o assunto, consulte javaspecialists.eu/archive/Issue056.html
Marco13
3

Use Thread.sleep(100);. A unidade de tempo é milissegundos

Por exemplo:

public class SleepMessages {
    public static void main(String args[])
        throws InterruptedException {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        for (int i = 0;
             i < importantInfo.length;
             i++) {
            //Pause for 4 seconds
            Thread.sleep(4000);
            //Print a message
            System.out.println(importantInfo[i]);
        }
    }
}
Bachan Joseph
fonte
1

Sei que esta é uma postagem muito antiga, mas isso pode ajudar alguém: Você pode criar um método; portanto, sempre que precisar fazer uma pausa, digite pause(1000)ou qualquer outro valor em milissegundo:

public static void pause(int ms) {
    try {
        Thread.sleep(ms);
    } catch (InterruptedException e) {
        System.err.format("IOException: %s%n", e);
    }
}

Isso é inserido logo acima do public static void main(String[] args), dentro da classe. Em seguida, para chamar o método, digite pause(ms)mas substitua mspelo número de milissegundos para pausar. Dessa forma, você não precisa inserir a instrução try-catch inteira sempre que quiser pausar.

dominic03
fonte