Je reçois une exception lors de l'utilisation de Thread.sleep (x) ou wait ()

343

J'ai essayé de retarder - ou de mettre en veille - mon programme Java, mais une erreur se produit.

Je ne peux pas utiliser Thread.sleep(x)ou wait(). Le même message d'erreur apparaît:

exception non signalée java.lang.InterruptedException; doit être attrapé ou déclaré jeté.

Y a-t-il une étape requise avant d'utiliser les méthodes Thread.sleep()ou wait()?

vincent bas
la source
8
Eh bien, c'est populaire. Il doit y avoir un nombre énorme de personnes qui doivent retarder leur programme Java de quelques secondes. Difficile à imaginer. Bien sûr, mettre le bon titre sur le message aiderait énormément.
Robert Harvey

Réponses:

575

Vous avez beaucoup de lecture devant vous. Des erreurs du compilateur à la gestion des exceptions, au filetage et aux interruptions de fil. Mais cela fera ce que vous voulez:

try {
    Thread.sleep(1000);                 //1000 milliseconds is one second.
} catch(InterruptedException ex) {
    Thread.currentThread().interrupt();
}
Konrad Garus
la source
1
merci pour votre aide, j'ai pu l'exécuter .. à côté, à quoi sert catch (interruptedException ex)
vincent low
4
Voir la réponse d'Abel. Google pour InterruptedException. Pour faire court: le fil peut être interrompu pendant le sommeil, et c'est une sorte d'exception qui doit être explicitement gérée.
Konrad Garus
8
Certaines réponses disent de ne rien faire sur l'exception, certains disent de lancer, cela indique d'interrompre (). Quelqu'un voudrait-il discuter de ce qui est approprié et pourquoi?
Suma
6
@Suma Il y a beaucoup de discussions à ce sujet, y compris Stack Overflow lui-même. Recherchez-le. Trop long pour un commentaire. Après quelques années, la seule réponse que j'ai est: cela dépend. Habituellement, la solution idéale est de mettre fin à tout ce que le thread fait gracieusement (par exemple, annuler cette transaction, rompre une boucle, etc.), mais cela dépend très du contexte.
Konrad Garus
alors à quoi sert une minuterie? pourriez-vous obtenir la même fonctionnalité avec une minuterie? J'ai lu le doc java, et il a mentionné quelque chose sur les retards, mais étant un débutant avec du code, je suis sur le point de terminer ma deuxième année de programmation au lycée, je ne suis pas tout à fait sûr si le retard dont il parle serait utile ici, ou même le bonne classe à utiliser
Ungeheuer
195

Comme d'autres utilisateurs l'ont dit, vous devez entourer votre appel d'un try{...} catch{...}bloc. Mais depuis la sortie de Java 1.5, il existe une classe TimeUnit qui fait la même chose que Thread.sleep (millis) mais est plus pratique. Vous pouvez choisir l'unité de temps pour l'opération de sommeil.

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
}

Il a également des méthodes supplémentaires: TimeUnit Oracle Documentation

Alexander Ivanov
la source
6
Voir d'autres réponses pour savoir par exemple comment entourer ces appels avec la try-catchgestion des exceptions requise .
Basil Bourque
2
N'oubliez pas "import java.util.concurrent.TimeUnit;"
codeur
13

Utilisez la construction de codage suivante pour gérer les exceptions

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

Mettez votre Thread.sleepbloc de capture d'essai

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

Lors de l'utilisation d' Android (la seule fois où j'utilise Java), je recommanderais d'utiliser un gestionnaire au lieu de mettre le fil en veille.

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);

Référence: http://developer.android.com/reference/android/os/Handler.html

Sindri Þór
la source
4
C'est pour Android pas pour Core Java
Ganesh Krishnan
3

Essaye ça:

try{

    Thread.sleep(100);
}catch(Exception e)
{
   System.out.println("Exception caught");
}
SlickJava
la source
8
N'est-ce pas une mauvaise pratique d'attraper Exceptionen Java?
Michael Dorst
2
Il vaut mieux attraper InterruptedException comme les autres réponses ici
devsaw
6
C'est ce qu'on appelle un `` gestionnaire d'exception Pokemon '' - je dois tous les attraper.
James Tayler
3

Mes façons d'ajouter du retard à un programme 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   
    }
}

C'est pour le délai séquentiel mais pour les délais de boucle, référez-vous à Java Delay / Wait .

DRBendanillo
la source
Veuillez noter que l'auto-promotion flagrante n'est pas autorisée ici. Voir le dernier point ici dans le centre d'aide . Vous pouvez cependant mettre le lien dans votre profil - c'est autorisé.
SL Barth - Rétablir Monica
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
}

par exemple:-

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
la source
0

Une manière plus simple d'attendre est d'utiliser System.currentTimeMillis(), qui renvoie le nombre de millisecondes depuis minuit le 1er janvier 1970 UTC. Par exemple, pour attendre 5 secondes:

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 cette façon, vous n'avez pas à vous occuper des threads et des exceptions. J'espère que cela t'aides!

Sam
la source
Cela consomme du CPU en attendant.
yacc
@yacc C'est vrai, mais c'est plus simple que d'utiliser des threads et n'utilise pas trop de CPU.
Sam
0

Utilisation java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Dormez une seconde ou

TimeUnit.MINUTES.sleep(1);

Dormez une minute.

Comme il s'agit d'une boucle, cela présente un problème inhérent - la dérive. Chaque fois que vous exécutez du code, puis que vous dormez, vous vous éloignerez un peu de l'exécution, par exemple, chaque seconde. Si c'est un problème, ne l'utilisez pas sleep.

De plus, sleepn'est pas très flexible en matière de contrôle.

Pour exécuter une tâche toutes les secondes ou avec un retard d'une seconde, je recommande fortement un [ ScheduledExecutorService] [1] et soit [ scheduleAtFixedRate] [2] ou [ scheduleWithFixedDelay] [3].

Pour exécuter la méthode myTasktoutes les secondes (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
la source
0

Thread.sleep() est simple pour les débutants et peut convenir aux tests unitaires et aux preuves de concept.

Mais s'il vous plaît NE PAS utiliser sleep()pour le code de production. Finalementsleep()Peut vous mordre gravement.

Meilleure pratique pour les applications Java multithread / multicœurs pour utiliser le concept "thread wait". Wait libère tous les verrous et moniteurs détenus par le thread, ce qui permet aux autres threads d'acquérir ces moniteurs et de continuer pendant que votre thread dort paisiblement.

Le code ci-dessous montre cette technique:

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 la mise en oeuvre:

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
la source
-2

Alternativement, si vous ne souhaitez pas traiter les threads, essayez cette méthode:

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

Il commence lorsque vous l'appelez et se termine lorsque le nombre de secondes s'est écoulé.

user2276378
la source
7
Cela consommerait du CPU pendant le temps de veille. Sur Thread.sleep (), le fil peut être replanifié.
Vivek Pandey
vous êtes ridi et il n'y a pas d'eau: D
M410
17
L'utilisateur 2276378 avait mal compris l'anglais de la question. OP a déclaré qu'il n'était "pas en mesure d'utiliser sommeil ou attente", ce que l'utilisateur2276378 pensait signifier qu'il ne pouvait pas les utiliser (ou n'était pas autorisé à les utiliser) et il a donc fourni une solution valide qui n'utilisait pas sommeil ou attente. Essayez de ne pas être trop dur L'anglais n'est pas la première langue de tout le monde.
David Newcomb