NetBeans / Java / nouvel indice: Thread.sommeil appelé en boucle
Dans NetBeans, il y a un nouvel indice qui dit: Thread.sommeil appelé en boucle.
Question 1: Comment/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 du code. Dites-moi dans ce cas si je devrais utiliser autre chose au lieu de Thread.Dormir dans une boucle. En bref, ceci est utilisé par un serveur qui écoute les connexions TCP du 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 que l'application attende jusqu'à ce qu'une session gratuite soit 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();
}
}
4 réponses
Appeler le sommeil dans une boucle entraîne généralement de mauvaises performances. Par exemple:
while (true) {
if (stream.available() > 0) {
// read input
}
sleep(MILLISECONDS);
}
Si millisecondes est trop grand, alors ce code prendra beaucoup de temps pour réaliser que l'entrée est disponible.
Si les millisecondes sont trop petites, ce code gaspillera beaucoup de ressources système pour vérifier les entrées qui ne sont pas encore arrivées.
Autres utilisations de sleep
dans une boucle sont généralement douteux ainsi. Il y a généralement un meilleur moyen.
Si c'est un problème, que devrais-je faire à la place?
Postez 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 configure l'exécuteur pour correspondre à la façon dont votre code fonctionne actuellement. Il y a un certain nombre d'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 qui est conçu pour faire quelque chose toutes les 10 secondes (mais n'est pas si critique que le moment précis est nécessaire). Nous avons beaucoup de ces "applications utilitaires" qui importent des données et d'autres tâches toutes les quelques minutes. C'est un moyen facile d'effectuer ces tâches et nous allons généralement définir l'intervalle de sommeil pour être très faible et utiliser un compteur afin que le programme reste réactif et peut 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 peut-il être un problème de dormir dans une boucle?
Les gens l'emploient 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?
Dépend de ce que vous faites. Bien qu'il soit dificile pour moi d'imaginer une situation où faire cela est la meilleure approche, je suppose que c'est possible aussi.
Vous pouvez consulter le tutoriel sur la concurrencede sur ce sujet.
Je pense que je rencontre une utilisation Tout à fait légitime de la méthode sleep()
en boucle.
Nous avons une connexion unidirectionnelle entre le serveur et le client. Ainsi, lorsque le client veut obtenir une communication asynchrone avec le serveur, il envoie un message au serveur et interroge périodiquement une réponse du serveur. Il faut un certain 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
~ délai d'attente