¿Cómo hago un retraso en Java?

343

Estoy tratando de hacer algo en Java y necesito algo para esperar / retrasar una cantidad de segundos en un bucle 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++;
}

Quiero construir un secuenciador por pasos y soy nuevo en Java. ¿Alguna sugerencia?

ardb
fuente
19
Uso Thread.Sleep().
Diminuto
2
Considere usar un temporizador
PeterMmm
2
¿Cuál es el propósito de esperar? ¿Estás esperando que ocurra cierto evento? Asegúrese de comprender lo que hace el método sleep ()
artdanil
@Tiny, NO es seguro.
Yousha Aleayoub
12
Es en realidad Thread.sleep(<milisecondsToSleep>). El sno debe ser capitalizado.
Benjamin

Respuestas:

678

Si quieres hacer una pausa, usa java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Para dormir por un segundo o

TimeUnit.MINUTES.sleep(1);

A dormir un minuto.

Como se trata de un bucle, esto presenta un problema inherente: la deriva. Cada vez que ejecute el código y luego duerma, perderá un poco la ejecución, por ejemplo, cada segundo. Si esto es un problema, no lo use sleep.

Además, sleepno es muy flexible cuando se trata de control.

Para ejecutar una tarea cada segundo o con un segundo de retraso, recomendaría encarecidamente a ScheduledExecutorServicey o scheduleAtFixedRateo scheduleWithFixedDelay.

Por ejemplo, para ejecutar el método 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");
}

Y en 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 la araña
fuente
1
@Matthew Moisen No pude ejecutar este ejemplo de Java 8. ¿Qué es la aplicación :: exactamente? Al cambiar myTask () a una lambda ejecutable, funciona: myTask ejecutable = () -> {...};
cómodo el
2
Es una referencia de método @comfytoday: sugiero comenzar con la documentación .
Boris the Spider
TimeUnit.SECONDS.wait(1)está lanzando IllegalMonitorStateExceptionJava 8.1 build 31 en Windows 6.3. En cambio, puedo usar Thread.sleep(1000)sin un try / catch.
John Meyer
1
En Java 8, en java.util.concurrent.TimeUnit obtienes Unhandled exception: java.lang.InterruptedExecutionpara elsleep(1)
Shai Alon
1
Debes rodearlo TimeUnit.SECONDS.sleep(1);contry catch
Shai Alon
148

Uso Thread.sleep(1000);

1000 es la cantidad de milisegundos que el programa hará una pausa.

try
{
    Thread.sleep(1000);
}
catch(InterruptedException ex)
{
    Thread.currentThread().interrupt();
}
Anju Aravind
fuente
55
No olvide registrar la excepción InterruptedException o nunca sabrá que este hilo fue interrumpido.
m0skit0
12
Tengo curiosidad por saber qué Thread.currentThread (). Interrupt (); hace aquí.
Brent212
1
ver: "¿Por qué tenemos que interrumpir el hilo de nuevo?" aquí: javaspecialists.eu/archive/Issue056.html
Tristán
5

utilizar este:

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

entonces puedes llamar a este método en cualquier lugar como:

        wait(1000);
Hecanet
fuente
3

Usar TimeUnit.SECONDS.sleep(1);o Thread.sleep(1000);es una forma aceptable de hacerlo. En ambos casos, debe atrapar lo InterruptedExceptionque hace que su código sea voluminoso. Hay una biblioteca Java de código abierto llamada MgntUtils (escrita por mí) que proporciona una utilidad que ya trata con el InterruptedExceptioninterior. Entonces su código solo incluiría una línea:

TimeUtils.sleepFor(1, TimeUnit.SECONDS);

Ver el javadoc aquí . Puede acceder a la biblioteca desde Maven Central o desde Github . El artículo que explica sobre la biblioteca se puede encontrar aquí.

Michael Gantman
fuente
2
Usar NOcatch (InterruptedException e) { /* empty */ } es una solución sensata aquí. Como mínimo, debe proporcionar alguna información de registro. Para obtener más información sobre el tema, consulte javaspecialists.eu/archive/Issue056.html
Marco13
3

Uso Thread.sleep(100);. La unidad de tiempo es milisegundos.

Por ejemplo:

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
fuente
1

Sé que esta es una publicación muy antigua, pero puede ayudar a alguien: puede crear un método, por lo que cada vez que necesite hacer una pausa, puede escribir pause(1000)o cualquier otro valor de milisegundos:

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

Esto se inserta justo encima de public static void main(String[] args), dentro de la clase. Luego, para invocar el método, escriba pause(ms)pero reemplace mscon el número de milisegundos para pausar. De esa manera, no tiene que insertar toda la declaración try-catch cuando quiera hacer una pausa.

dominic03
fuente