Recibo una excepción cuando uso Thread.sleep (x) o wait ()

343

He intentado retrasar, o poner en suspensión, mi programa Java, pero se produce un error.

No puedo usar Thread.sleep(x)o wait(). Aparece el mismo mensaje de error:

excepción no declarada java.lang.InterruptedException; debe ser atrapado o declarado ser arrojado.

¿Se requiere algún paso antes de usar los métodos Thread.sleep()o wait()?

Vincent Low
fuente
8
Bueno, esto es popular. Debe haber una enorme cantidad de personas que necesiten retrasar su programa Java durante unos segundos. Difícil de imaginar. Por supuesto, poner el título correcto en la publicación sería de gran ayuda.
Robert Harvey

Respuestas:

575

Tienes mucha lectura por delante. Desde errores del compilador hasta manejo de excepciones, subprocesos e interrupciones de subprocesos. Pero esto hará lo que quieras:

try {
    Thread.sleep(1000);                 //1000 milliseconds is one second.
} catch(InterruptedException ex) {
    Thread.currentThread().interrupt();
}
Konrad Garus
fuente
1
gracias por su ayuda, pude ejecutarlo ... además, ¿para qué sirve catch (interruptedException ex)
vincent low
44
Ver respuesta de Abel. Google for InterruptedException. En pocas palabras: el hilo se puede interrumpir mientras se duerme, y esta es una especie de excepción que debe manejarse explícitamente.
Konrad Garus
8
Algunas respuestas le dicen que no haga nada en la excepción, algunas dicen que lance, esto le dice a interrupt (). ¿A alguien le gustaría discutir cuál es apropiado y por qué?
Suma
66
@Suma Hay mucha discusión al respecto, incluido Stack Overflow. Solo búscalo. Demasiado tiempo para un comentario. Después de unos años, la única respuesta que tengo es: depende. Por lo general, la solución ideal es terminar lo que sea que el hilo esté haciendo con gracia (por ejemplo, revertir esta transacción, romper un ciclo, etc.), pero eso depende mucho del contexto.
Konrad Garus
entonces, ¿para qué sirve un temporizador? ¿podría lograr la misma funcionalidad con un temporizador? Leí el documento de Java, y mencionó algo acerca de los retrasos, pero como soy un novato con código, estoy a punto de terminar mi segundo año de programación de la escuela secundaria, no estoy completamente seguro de si el retraso del que habla sería útil aquí, o incluso el clase correcta para usar
Ungeheuer
195

Como han dicho otros usuarios, debe rodear su llamada con un try{...} catch{...}bloqueo. Pero desde que se lanzó Java 1.5, hay una clase TimeUnit que hace lo mismo que Thread.sleep (millis) pero es más conveniente. Puede elegir la unidad de tiempo para la operación de reposo.

try {
    TimeUnit.NANOSECONDS.sleep(100);
    TimeUnit.MICROSECONDS.sleep(100);
    TimeUnit.MILLISECONDS.sleep(100);
    TimeUnit.SECONDS.sleep(100);
    TimeUnit.MINUTES.sleep(100);
    TimeUnit.HOURS.sleep(100);
    TimeUnit.DAYS.sleep(100);
} catch (InterruptedException e) {
    //Handle exception
}

También tiene métodos adicionales: TimeUnit Oracle Documentation

Alexander Ivanov
fuente
66
Consulte otras respuestas, por ejemplo, sobre cómo rodear estas llamadas con el try-catchmanejo de excepciones requerido .
Basil Bourque
2
No olvide "import java.util.concurrent.TimeUnit;"
codificador
13

Use la siguiente construcción de codificación para manejar excepciones

try {
  Thread.sleep(1000);
} catch (InterruptedException ie) {
    //Handle exception
}
Jatin
fuente
8

Prueba tu Thread.sleepbloque de captura

try {
    //thread to sleep for the specified number of milliseconds
    Thread.sleep(100);
} catch ( java.lang.InterruptedException ie) {
    System.out.println(ie);
}
JoseK
fuente
7

Cuando uso Android (la única vez que uso Java) recomendaría usar un controlador en lugar de poner el hilo a dormir.

final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            Log.i(TAG, "I've waited for two hole seconds to show this!");

        }
    }, 2000);

Referencia: http://developer.android.com/reference/android/os/Handler.html

Sindri Þór
fuente
44
Esto es para Android, no para Core Java
Ganesh Krishnan
3

Prueba esto:

try{

    Thread.sleep(100);
}catch(Exception e)
{
   System.out.println("Exception caught");
}
SlickJava
fuente
8
¿No es una mala práctica atrapar Exceptionen Java?
Michael Dorst el
2
Es mejor capturar la InterruptedException como las otras respuestas aquí
devsaw
66
Esto se llama un 'Controlador de excepciones de Pokémon': tengo que atraparlos a todos.
James Tayler
3

Mis formas de agregar demora a un programa Java.

public void pause1(long sleeptime) {
    try {
        Thread.sleep(sleeptime);
    } catch (InterruptedException ex) {
        //ToCatchOrNot
    }
}

public void pause2(long sleeptime) {
    Object obj = new Object();
    if (sleeptime > 0) {
        synchronized (obj) {
            try {
                obj.wait(sleeptime);
            } catch (InterruptedException ex) {
                //ToCatchOrNot
            }
        }
    }
}
public void pause3(long sleeptime) {
    expectedtime = System.currentTimeMillis() + sleeptime;
    while (System.currentTimeMillis() < expectedtime) {
        //Empty Loop   
    }
}

Esto es para el retraso secuencial, pero para los retrasos de bucle, consulte Java Delay / Wait .

DRBendanillo
fuente
Tenga en cuenta que la autopromoción flagrante no está permitida aquí. Vea el último punto aquí en el Centro de ayuda . Sin embargo, puede poner el enlace en su perfil, eso está permitido.
SL Barth - Restablece a Monica el
3
public static void main(String[] args) throws InterruptedException {
  //type code


  short z=1000;
  Thread.sleep(z);/*will provide 1 second delay. alter data type of z or value of z for longer delays required */

  //type code
}

p.ej:-

class TypeCasting {

  public static void main(String[] args) throws InterruptedException {
    short f = 1;
    int a = 123687889;
    short b = 2;
    long c = 4567;
    long d=45;
    short z=1000;
    System.out.println("Value of a,b and c are\n" + a + "\n" + b + "\n" + c + "respectively");
    c = a;
    b = (short) c;
    System.out.println("Typecasting...........");
    Thread.sleep(z);
    System.out.println("Value of B after Typecasting" + b);
    System.out.println("Value of A is" + a);


  }
}
c0der
fuente
0

Una forma más simple de esperar es usar System.currentTimeMillis(), que devuelve el número de milisegundos desde la medianoche del 1 de enero de 1970 UTC. Por ejemplo, para esperar 5 segundos:

public static void main(String[] args) {
    //some code
    long original = System.currentTimeMillis();
    while (true) {
        if (System.currentTimeMillis - original >= 5000) {
            break;
        }
    }
    //more code after waiting
}

De esta manera, no tiene que perder el tiempo con hilos y excepciones. ¡Espero que esto ayude!

Sam
fuente
Esto consume CPU mientras espera.
yacc
@yacc Esto es cierto, pero es más simple que usar hilos y no usa demasiada CPU.
Sam
0

Uso java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Duerme un segundo o

TimeUnit.MINUTES.sleep(1);

Duerme 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 retraso de un segundo, recomendaría encarecidamente un [ ScheduledExecutorService] [1] y [ scheduleAtFixedRate] [2] o [scheduleWithFixedDelay ] [3].

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");
}
Gavriel Cohen
fuente
0

Thread.sleep() es simple para los principiantes y puede ser apropiado para pruebas unitarias y pruebas de concepto.

Pero por favor NO lo use sleep()para el código de producción. Eventualmente sleep()puede morderte mucho.

La mejor práctica para aplicaciones java multiproceso / multinúcleo para utilizar el concepto de "hilo de espera". Esperar libera todos los bloqueos y monitores que mantiene el hilo, lo que permite que otros hilos adquieran esos monitores y continúen mientras su hilo duerme pacíficamente.

El siguiente código demuestra esa técnica:

import java.util.concurrent.TimeUnit;
public class DelaySample {
    public static void main(String[] args) {
       DelayUtil d = new DelayUtil();
       System.out.println("started:"+ new Date());
       d.delay(500);
       System.out.println("half second after:"+ new Date());
       d.delay(1, TimeUnit.MINUTES); 
       System.out.println("1 minute after:"+ new Date());
    }
}

DelayUtil implementación:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class DelayUtil {
    /** 
    *  Delays the current thread execution. 
    *  The thread loses ownership of any monitors. 
    *  Quits immediately if the thread is interrupted
    *  
    * @param durationInMillis the time duration in milliseconds
    */
   public void delay(final long durationInMillis) {
      delay(durationInMillis, TimeUnit.MILLISECONDS);
   }

   /** 
    * @param duration the time duration in the given {@code sourceUnit}
    * @param unit
    */
    public void delay(final long duration, final TimeUnit unit) {
        long currentTime = System.currentTimeMillis();
        long deadline = currentTime+unit.toMillis(duration);
        ReentrantLock lock = new ReentrantLock();
        Condition waitCondition = lock.newCondition();

        while ((deadline-currentTime)>0) {
            try {
                lock.lockInterruptibly();    
                waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            } finally {
                lock.unlock();
            }
            currentTime = System.currentTimeMillis();
        }
    }
}
Valchkou
fuente
-2

Alternativamente, si no quieres lidiar con hilos, prueba este método:

public static void pause(int seconds){
    Date start = new Date();
    Date end = new Date();
    while(end.getTime() - start.getTime() < seconds * 1000){
        end = new Date();
    }
}

Comienza cuando lo llamas y termina cuando han pasado la cantidad de segundos.

usuario2276378
fuente
77
Esto consumiría la CPU durante el tiempo de suspensión. En Thread.sleep () el hilo se puede reprogramar.
Vivek Pandey
eres ridi y no hay agua: D
M410
17
user2276378 había entendido mal el inglés de la pregunta. OP dijo que era "incapaz de usar el sueño o la espera", lo que el usuario 2276378 pensó que significaba que no podía usarlos (o que no se les permitió usarlos), por lo que proporcionó una solución válida que no usaba el sueño o la espera. Intenta no ser demasiado duro El inglés no es el primer idioma de todos.
David Newcomb