web-dev-qa-db-fra.com

Pourquoi Thread.sleep est mauvais à utiliser

Toutes mes excuses pour cette question répétée, mais je n'ai pas encore trouvé de réponses satisfaisantes. La plupart des questions avaient leur propre cas d'utilisation spécifique:
Java - alternative à thread.sleep
Existe-t-il un moyen meilleur ou alternatif d'ignorer/d'éviter d'utiliser Thread.sleep (1000) en Java?

Ma question concerne le cas d'utilisation très générique. Attendez la fin d'une condition. Faites une opération. Vérifiez une condition. Si la condition n'est pas vraie, attendez un certain temps et recommencez la même opération.

Par exemple Envisagez une méthode qui crée une table DynamoDB en appelant sa table createAPI. La table DynamoDB met du temps à devenir active pour que cette méthode appelle son API DescribeTable pour interroger l'état à intervalles réguliers jusqu'à un certain temps (disons 5 minutes - l'écart dû à la planification des threads est acceptable). Renvoie true si la table devient active dans 5 minutes sinon, une exception est levée.

Voici un pseudo code:

public void createDynamoDBTable(String name) {
  //call create table API to initiate table creation

  //wait for table to become active
  long endTime = System.currentTimeMillis() + MAX_WAIT_TIME_FOR_TABLE_CREATE;

  while(System.currentTimeMillis() < endTime) {
    boolean status =  //call DescribeTable API to get status;
    if(status) {
         //status is now true, return
         return
    } else {
        try {
            Thread.sleep(10*1000);
        } catch(InterruptedException e) {
        }
    }
  }

  throw new RuntimeException("Table still not created");
}

Je comprends qu'en utilisant Thread.sleep bloque le thread actuel, consommant ainsi des ressources. mais dans une application de taille moyenne, un thread est-il un gros problème?
J'ai lu quelque part qui utilise ScheduledThreadPoolExecutor et je fais ce sondage d'état ici. Mais encore une fois, nous devrions initialiser ce pool avec au moins 1 thread où la méthode exécutable pour effectuer l'interrogation s'exécuterait.

Des suggestions sur la raison pour laquelle utiliser Thread.sleep est dit être une si mauvaise idée et quelles sont les options alternatives pour y parvenir comme ci-dessus.

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

27
RandomQuestion

C'est bien d'utiliser Thread.sleep dans cette situation. La raison pour laquelle les gens découragent Thread.sleep est parce qu'il est fréquemment utilisé dans une mauvaise tentative pour corriger une condition de concurrence critique, utilisé lorsque la synchronisation basée sur les notifications est un bien meilleur choix, etc.

Dans ce cas, AFAIK vous n'avez pas d'option mais interrogez car l'API ne vous fournit pas de notifications. Je peux également voir que c'est une opération peu fréquente parce que vous n'allez probablement pas créer des milliers de tables.

Par conséquent, je trouve bon d'utiliser Thread.sleep ici. Comme vous l'avez dit, la création d'un thread séparé lorsque vous allez bloquer le thread actuel semble de toute façon compliquer les choses sans mérite.

34
Enno Shioji

Oui, il faut essayer d'éviter l'utilisation de Thread.sleep (x) mais cela ne doit pas être totalement oublié:

Pourquoi cela devrait être évité

  • Il ne libère pas le verrou
  • Cela ne garantit pas que l'exécution commencera après le temps de sommeil (il peut donc continuer à attendre indéfiniment - évidemment un cas rare)
  • Si nous mettons par erreur un thread de traitement de premier plan en veille, nous ne pourrons pas fermer cette application avant x millisecondes.
  • Nous avons maintenant plein à craquer avec un nouveau package de concurrence pour des problèmes spécifiques (comme les modèles de conception (bien sûr pas exactement), pourquoi utiliser alors Thread.sleep (x).

Où utiliser Thread.sleep (x):

  • Pour fournir des retards dans les threads d'exécution en arrière-plan
  • Et quelques autres.
6
Amandeep