NetBeans / Java / Nouvel indice: Thread.sleep appelé en boucle

Dans NetBeans, il y a un nouvel indice qui dit: Thread.sleep appelé en boucle.

Question 1: Comment et quand peut-il être difficile de dormir en boucle?

Question 2: Si c’est un problème, que dois-je faire à la place?

MISE À JOUR: Question 3: Voici du code. Dites-moi dans ce cas si je devrais utiliser autre chose que Thread.Sleep dans une boucle. En bref, ceci est utilisé par un serveur qui écoute les connexions TCP client. Le mode veille est utilisé ici si le nombre maximal de sessions avec les clients est atteint. Dans cette situation, je souhaite que l’application attende qu’une session libre devienne disponible.

public class SessionManager { private static final int DEFAULT_PORT = 7500; private static final int SLEEP_TIME = 200; private final DatabaseManager database = new DatabaseManager(); private final ServerSocket serverSocket = new ServerSocket(DEFAULT_PORT); public SessionManager() throws IOException, SQLException { } public void listen() { while (true) if (Session.getSessionCount() < Session.getMaxSessionCount()) try { new Thread(new Session(database, serverSocket.accept())).start(); } catch (IOException ex) { ex.printStackTrace(); } else try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException ex) { ex.printStackTrace(); } } public static void main(String[] args) throws IOException, SQLException { new SessionManager().listen(); } } 

L’appel du sumil en boucle entraîne généralement de mauvaises performances. Par exemple:

 while (true) { if (stream.available() > 0) { // read input } sleep(MILLISECONDS); } 

Si MILLISECONDS est trop volumineux, ce code mettra beaucoup de temps à réaliser que cette entrée est disponible.

Si MILLISECONDS est trop petit, alors ce code gaspillera beaucoup de ressources système pour vérifier les entrées qui ne sont pas encore arrivées.

Les autres utilisations du sleep dans une boucle sont également discutables. Il y a généralement une meilleure façon.

Si c’est un problème, que dois-je faire à la place?

Affichez le code et nous pourrons peut-être vous donner une réponse raisonnable.

MODIFIER

IMO, une meilleure façon de résoudre le problème consiste à utiliser un ThreadPoolExecutor .

Quelque chose comme ça:

 public void listen() { BlockingQueue queue = new SynchronousQueue(); ThreadPoolExecutor executor = new ThreadPoolExecutor( 1, Session.getMaxSessionCount(), 100, TimeUnit.SECONDS, queue); while (true) { try { queue.submit(new Session(database, serverSocket.accept())); } catch (IOException ex) { ex.printStackTrace(); } } } 

Cela configure l’exécuteur en fonction de la manière dont fonctionne votre code. Il y a plusieurs autres façons de le faire. voir le lien javadoc ci-dessus.

Comme d’autres l’ont dit, cela dépend de l’utilisation. Une utilisation légitime serait un programme conçu pour faire quelque chose toutes les 10 secondes (mais qui n’est pas si critique que le timing exact est nécessaire). Nous avons beaucoup de ces “applications utilitaires” qui importent des données et autres tâches similaires toutes les quelques minutes. C’est un moyen facile d’exécuter ces tâches et nous définirons généralement l’intervalle de sumil très bas et utiliser un compteur pour que le programme rest réactif et puisse sortir facilement.

 int count = 0; while (true) { try { // Wait for 1 second. Thread.sleep(1000); } catch (InterruptedException ex) {} // Check to see if the program should exit due to other conditions. if (shouldExit()) break; // Is 10 seconds up yet? If not, just loop back around. count++; if (count < 10) continue; // 10 seconds is up. Reset the counter and do something important. count = 0; this.doSomething(); } 

Comment / quand est-ce que ça peut être un problème de dormir en boucle?
Les gens l’utilisent parfois à la place de méthodes de synchronisation appropriées (comme wait / notify).

Si c’est un problème, que dois-je faire à la place?
Cela dépend de ce que vous faites. Bien que ce soit difficile pour moi d’imaginer une situation où faire ceci est la meilleure approche, je suppose que c’est aussi possible.

Vous pouvez consulter le didacticiel sur la concurrence de Sun à ce sujet.

Je pense que je rencontre une utilisation complètement légitime de sleep() méthode sleep() en boucle.

Nous avons une connexion à sens unique entre le serveur et le client. Ainsi, lorsque le client souhaite établir une communication asynchrone avec le serveur, il envoie un message au serveur et interroge périodiquement le serveur pour obtenir des réponses. Il doit y avoir un intervalle de délai d’attente.

 Response resp = null; for (int i = 0; i < POLL_REPEAT && resp == null; i++) { try { Thread.sleep(POLL_INTERVAL); } catch (InterruptedException ie) { } resp = server.getResponse(workflowId); } 

POLL_REPEAT * POLL_INTERVAL ~ intervalle TIMEOUT