web-dev-qa-db-fra.com

Thread.sleep () dans une boucle while

Je remarque que NetBeans m’avertit de l’utilisation de Thread.sleep () dans une boucle while de mon code Java. J’ai donc fait quelques recherches sur le sujet. Il semble qu’il s’agisse principalement de problèmes de performances, où votre condition tout peut devenir vraie tant que le compteur est encore en train de dormir, ce qui vous fait perdre du temps en attendant que vous attendiez la prochaine itération. Tout cela a du sens.

Mon application doit contacter un système distant et interroger périodiquement l'état d'une opération, en attendant la fin de l'opération avant d'envoyer la demande suivante. Pour le moment, le code fait logiquement ceci:

String state = get state via RPC call
while (!state.equals("complete")) {
    Thread.sleep(10000); // Wait 10 seconds
    state = {update state via RPC call}
}

Étant donné que la circonstance est en train de vérifier une opération à distance (ce qui est un processus assez coûteux, car elle dure plusieurs secondes), s'agit-il d'une utilisation valide de Thread.sleep () dans une boucle while? Existe-t-il un meilleur moyen de structurer cette logique? J'ai vu quelques exemples où je pourrais utiliser une classe Timer, mais je ne vois pas les avantages, car cela semble résumer à la même logique simple ci-dessus, mais avec beaucoup plus de complexité.

Gardez à l'esprit que le système distant dans ce cas n'est ni sous mon contrôle direct, ni écrit en Java. Par conséquent, changer cette fin pour qu'il soit plus "coopératif" dans ce scénario n'est pas une option. Ma seule option pour mettre à jour la valeur de mon application pour state est de créer et d'envoyer un message XML, de recevoir une réponse, de l'analyser, puis d'extraire l'information dont j'ai besoin.

Toutes les suggestions ou commentaires seraient les bienvenus.

21
Steve Ferguson

À moins que votre système distant ne puisse émettre un événement ou vous avertir de manière asynchrone, je ne pense pas que ce qui précède soit déraisonnable. Vous devez équilibrer votre sleep() time par rapport au temps/charge généré par l'appel RPC, mais je pense que c'est le seul problème et que ce qui précède ne semble pas du tout préoccupé.

13
Brian Agnew

Sans pouvoir modifier l'extrémité distante pour fournir une notification "Push" indiquant que cela est fait avec son processus de longue durée, c'est à peu près aussi bien que vous pourrez le faire. Tant que la durée de Thread.sleep est longue comparée au coût de l'interrogation, vous devriez être OK.

4
Steven Schlansker

Vous devriez (presque) ne jamais utiliser le sommeil car il est très inefficace et que ce n’est pas une bonne pratique. Utilisez toujours des verrous et des variables de condition là où les threads se signalent. Voir Mike Dahlin's Normes de codage pour la programmation avec des threads

Un modèle est:

public class Foo{
  private Lock lock;
  private Condition c1;
  private Condition c2;

  public Foo()
  {
    lock = new SimpleLock();
    c1 = lock.newCondition();
    c2 = lock.newCondition();
    ...
  }

  public void doIt()
  {
    try{
      lock.lock();
      ...
      while(...){
        c1.awaitUninterruptibly();
      }
      ...
      c2.signal();
    }
    finally{
      lock.unlock();
    }
  }
}
0
Cemre