Java: Est - `while (true) { ... } " en boucle dans un thread de mauvais? Quelle est l'alternative?
Est while (true) { ... }
boucle dans les threads mauvais? Quelle est l'alternative?
Mise à jour; ce que j'essaie de...
J'ai ~de 10 000 threads, chacun de consommer les messages de leurs files d'attente privées. J'ai un thread qui produit des messages un par un et de les mettre dans la bonne file d'attente du consommateur. Chaque thread consommateur est en boucle, la vérification d'un message s'affiche dans la file d'attente et de la traiter.
À L'Intérieur Consumer.java:
@Override
public void run() {
while (true) {
Message msg = messageQueue.poll();
if (msg != null) {
... //do something with the message
}
}
}
Le Producteur est en train de mettre des messages à l'intérieur des Consommateurs files d'attente de messages à un rythme rapide (plusieurs millions de messages par seconde). Les consommateurs devraient traiter ces messages aussi vite que possible!
Remarque: le while (true) { ... }
est terminée par un KILL message envoyé par le Producteur de son dernier message. Cependant, ma question est sur la bonne façon de le faire ce passage de message...
Veuillez voir la nouvelle question, au sujet de cette conception.
- Pourquoi ne pas vous donner plus de détails sur ce que vous essayez d'atteindre et nous allons vous dire si il y a une meilleure façon de le faire.
@Ryan:
Mis à jour; s'il vous plaît prendre un coup d'oeil!- 10000 fils semble être une mauvaise idée, car il peut y avoir des frais généraux associés à chaque thread...
@Colen:
Veuillez voir ma nouvelle question, car je pensais que c'était une mauvaise idée aussi... Quelle est l'alternative? stackoverflow.com/questions/3367383/...- La surcharge de 10k threads de l'extrême
Willi Schönborn:
Alors, quelle est l'alternative?- si vous utilisez un certain temps au lieu d'une instruction if à l'intérieur de votre thread - est-ce à dire que vous créez une nouvelle boucle à chaque fois que votre thread s'exécute?
Vous devez vous connecter pour publier un commentaire.
Au lieu de boucle pour toujours et de le casser ou de retour, vous pouvez choisir de vérifier l'état d'interruption.
Si vos fils sont des tâches gérées par un ExecutorService, vous pouvez les avoir tous en fin gracieusement simplement en appelant shutdownNow().
update
méthode d'un observateur... je ne sais pas combien de temps cela va prendre pour déclencher la méthode de manière aléatoirewait(1000)
ne marchera pas ici.......peut-être? Une certaine sorte de sortir le drapeau est souvent utilisée pour contrôler le thread en cours d'exécution.
stop_running
changement à false, une fois que la boucle commence? C'est ce que je pense que la plupart des gens se demandentPas, en soi, pas. Vous pouvez toujours en liberté sous caution à l'aide de
break
oureturn
. Assurez-vous de réellement faire (à un point)Le problème est ce qui se passe quand votre fils n'a rien à faire? Si vous venez de faire une boucle autour et autour de la vérification d'une condition, votre thread va manger toute la CPU ne rien faire. Donc, assurez-vous d'utiliser
wait
à cause de votre fil pour bloquer, ousleep
si vous n'avez pas de quoiwait
sur.Dépend de la définition de "mauvais". Cela signifie que la personne en essayant de lire le code est à chercher ailleurs pour la raison que la boucle se termine. Qui peut le rendre moins lisible.
Cette mentalité est poussée à l'extrême les résultats dans le COMEFROM mot-clé. http://en.wikipedia.org/wiki/COMEFROM
Il est préférable d'avoir de la résiliation de la condition sur la
while (...)
ligne, mais parfois la résiliation condition est quelque chose que vous ne pouvez tester quelque part profondément à l'intérieur de la boucle. Alors qu'est ce quebreak
est pour la (ou des exceptions). En fait, peut-être que votre fils doit toujours courir jusqu'à ce que votre programme se termine (avecSystem.exit
); puiswhile (true)
est vraiment le droit.Mais peut-être que vous vous dites à propos de ce qu'il devrait aller à l'intérieur de la boucle. Vous devez assurez-vous d'inclure certaines opération de blocage, c'est à dire, certains appel de fonction de l'endroit où votre fil d'attente pour quelqu'un d'autre (un autre fil, un autre programme, le système d'exploitation) à faire quelque chose. C'est typiquement
Condition.wait
si vous êtes à la programmation avec des serrures, ou par la lecture d'un message de la file d'attente, ou par la lecture d'un fichier ou d'une prise réseau, ou d'un autre blocage I/O operation.Noter que
sleep
est généralement pas assez bon. Vous ne pouvez pas savoir quand les autres participants vont faire quelque chose, donc il n'y a aucun moyen d'éviter de se réveiller trop souvent (et donc de brûler plus de temps CPU inutilement) ou trop rarement (donc pas de réagir aux événements en temps opportun). Toujours la conception de votre système de sorte que lorsqu'un thread a terminé son travail, il le notifie à celui qui est en attente sur ce travail (souvent avecCondition.signal
ou par adhésion).Généralement, vous aurez envie de
wait
sur une ressource d'un certain type pour faire le travail, qui cache réelle de filetage de détails auprès de vous. On dirait que tu voulais mettre en place votre propre spinlock.Voici un tutoriel sur le verrouillage, j'ai trouvé que je google.
J'ai l'habitude d'aller avec un attribut de classe boolean appelé "terminé", puis le fils exécuter les méthodes de ressembler à
Vous pouvez ensuite définir done=true pour tuer la boucle. Cela peut être fait à partir de l'intérieur de la boucle, ou vous pouvez avoir une autre méthode qui définit, alors que d'autres threads peuvent tirer la prise.
while (true)
n'est pas mauvais, si il ya un moyen de sortir de la boucle sinon, l'appel sera exécuté indéfiniment.Pour 10000 threads faire la
while(true)
appel est une mauvaise pratique...pourquoi ne pas avoir unsleep()
sur le fil pour permettre à d'autres threads de s'exécuter ou d'une stratégie de sortie si le fil de fin de l'exécution?On dirait que vous êtes occupé attente, en supposant un standard
BlockingQueue
. Utilisationtake
au lieu depoll
.Autre que cela,
for (;;)
est plus agréable que dewhile (true)
, de l'OMI.D'abord, la réponse à ce problème en Pâte Lea:
http://gee.cs.oswego.edu/dl/html/j9mm.html
Thead.onSpinWait a été introduit avec Java 9. Il pourrait ressembler à ceci.
https://docs.oracle.com/javase/9/docs/api/java/lang/Thread.html#onSpinWait--
Si je devais faire ce que vous parlez, je voudrais essayer ceci:
Cela vous permet de vous assurer que vous n'obtenez pas de modifications simultanées exepction sur votre messageQueue, ainsi que lorsqu'il n'y a pas de message, vous ne serez pas en utilisant le temps CPU dans le while(true) en boucle. Maintenant, vous avez juste besoin de faire en sorte que lorsque vous ajoutez quelque chose à votre messageQueue vous pouvez appeler
lock.notifyAll()
de sorte que le fil sera de savoir afin d'utiliser de nouveau.