49 votes

NetBeans / Java / Nouveau conseil: Thread.sleep appelé en boucle

Dans NetBeans, il y a un nouvel indice qui dit: Thread.sommeil appelée dans la boucle.

Question 1: Comment et quand peut-il être un problème pour dormir dans une boucle?

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

Mise à JOUR: Question 3: Voici une partie du code. Dites-moi, dans ce cas, si je dois être en utilisant quelque chose d'autre à la place du Fil.Dormir dans une boucle. En bref, il est utilisé par un serveur qui écoute les connexions TCP de client. Le sommeil est utilisé ici dans le cas où le nombre maximum de sessions avec les clients est atteint. Dans cette situation, je veux de l'application d'attendre la fin d'une session gratuite est 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();
}
}

22voto

Stephen C Points 255558

L'appel de dormir dans une boucle conduit généralement à une mauvaise performance. Par exemple:

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

Si MILLISECONDES est trop grande, alors ce code va prendre beaucoup de temps pour réaliser cette entrée est disponible.

Si MILLISECONDES est trop petit, ce code va perdre beaucoup de ressources du système de vérification pour une entrée qui n'était pas encore arrivé.

D'autres utilisations de l' sleep dans une boucle sont généralement douteux ainsi. Il y a généralement une meilleure façon.

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

Poste le code et peut-être que nous pouvons vous donner une réponse sensée.

MODIFIER

OMI, une meilleure façon de résoudre le problème est d'utiliser un ThreadPoolExecutor.

Quelque chose comme ceci:

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 permet de configurer l'exécuteur testamentaire pour correspondre à la façon dont votre code fonctionne actuellement. Il y a un certain nombre d'autres moyens de le faire; voir la javadoc lien ci-dessus.

5voto

java nut Points 41

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 n'est pas si critique qu'un timing exact est nécessaire). Nous avons beaucoup de ces "applications utilitaires" qui importent des données et d'autres tâches similaires toutes les quelques minutes. Il s’agit d’un moyen simple d’exécuter ces tâches. Nous définissons généralement l’intervalle de veille très bas et utilisons un compteur pour que le programme reste 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();
}
 

4voto

Ondrej Bozek Points 1988

Je pense avoir rencontré une utilisation tout à fait légitime de la méthode sleep() en boucle.

Nous avons une connexion à sens unique entre serveur et 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 une réponse. 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

1voto

Nikita Rybak Points 36641

Comment et quand peut-il être un problème pour dormir dans une boucle?
Parfois, les gens l'utilisent à la place d'une synchronisation correcte des méthodes (comme wait/notify).

Si c'est un problème, que dois-je faire à la place?
Dépend de ce que vous faites. Même si c'est dificile pour moi d'imaginer une situation où cette opération est la meilleure approche, je suppose que c'est possible aussi.

Vous pouvez le vérifier Soleil de simultanéité de tutoriel sur ce sujet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X