J'ai défini un fil et je veux l'exécuter à l'aide d'une boucle. Donc, ce fil doit fonctionner dans la boucle et se casser dans un certain temps et exécuter à nouveau la boucle. p>
S'il vous plaît je n'ai aucune idée de la façon de faire cela. Quelqu'un peut-il me guider. p>
5 Réponses :
Je ne peux que vous donner une suggestion seulement. Vous pouvez définir un drapeau comme IsthreadRunning, puis lorsque ce drapeau est vrai, vous exécutez la boucle, si ce n'est pas vrai, vous êtes hors de la boucle. À propos de la diffusion de la boucle à nouveau, je pense que vous pouvez créer un nouveau fil pour cela. Voici quelques extraits de code:
public class A extends Thread {
public boolean isThreadRunning = true;
public void run() {
while(isThreadRunning) {
// do task
}
}
}
Vous avez estimé que vous avez estimé des problèmes de concurrence - sans synchronisation appropriée ni spécificateur volatil, le fil peut ne pas voir le changement sur le drapeau
@Ravig: C'est juste un extrait de code, et je m'attends à ce que la question mec sait comment créer une classe s'étend sur le thread, après avoir exécuté la méthode. @MDMA: Comment ça ne voit pas, si l'autre thread change le drapeau, dans la boucle suivante, ce fil se déroule dans le moment et il verra que l'ISthreadRunning est faux, et cela arrêtera la boucle, non?
@vodkhang, aucune garantie ... Le fil peut voir que le drapeau isthreadrunning est défini ou qu'il peut jamais b> voir qu'il était défini. La variable peut être mise en cache thread-localement et sauf si vous faites quelque chose à explicitement B> mis à jour la variable mise en cache, il peut ne jamais être mis à jour. Volatile garantit que la variable n'est jamais mise en cache de thread-localement, donc toutes les modifications sont Toujours B> visibles à tous les threads.
Petite note. J'ai appris que vous devriez rarement prolonger le fil, et à la place runnable. L'extension d'un fil indique essentiellement une mise en oeuvre spécifique d'un thread, alors que l'extension d'un moyen runnable peut être exécuté dans un fil spécifique.
Je suis d'accord, pour moi, prolonge le thread signifie que nous voulons également avoir d'autres méthodes à partir du fil de superclasse.
Écrivez votre méthode d'exécution de votre thread comme celui-ci dans le code ci-dessus, la boucle est une boucle infinie qui exécutera chaque seconde (1000 milli secondes) et votre logique sera exécutée Seulement si la condition satisfaite. p> Si vous souhaitez augmenter le temps de pause à 2 secondes, changez 1000L code> sur 2000L code> p> p> p> P> P> P >
Merci pour les réponses rapides. Appréciez-les tous. Mon thread reconnaît une voix. Cela fait à l'aide d'une API de reconnaissance vocale. Je veux donc que ma demande reconnaisse chaque fois qu'un utilisateur dise quelque chose. Pour cela, j'ai besoin d'avoir une boucle et chaque fois qu'il vérifie l'entrée vocale et la sortie sur certaines fonctions. Donc, mon fil a cette reconnaissance vocale. Donc, dois-je faire boucler le fil dans ma classe principale ou puis-je faire une boucle de la fonction de reconnaissance vocale et de rompre et de produire quoi que ce soit par temps donné. Comme Ravig, dit exécuter toutes certaines secondes.
Pas besoin d'écrire une boucle dans la méthode principale. Lorsque vous démarrez le thread, en utilisant la méthode thread.Start (), votre méthode d'exécution sera exécutée. Dans la boucle tandis que vous allez écrire ce que vous vouliez exécuter.
Ceci est réellement mauvais, vous devriez plutôt utiliser l'interruption et le fichier thread.yield () code> sauf si vous voulez vraiment spécifiquement le thread actuel inactif pour sur i> le temps donné - Thread.sleep () code> ne garantit pas que le thread actuel va attendre l'heure spécifiée, il essaie simplement de dormir le fil actuel pendant l'heure spécifiée.
Java a un mécanisme intégré pour avoir un thread fait quelque chose puis attendre un moment de le refaire, appelé minuterie code>. Vous pouvez mettre ce qui serait à l'intérieur de votre boucle à l'intérieur de la méthode code> d'un TIMERTASK CODE>, puis indiquez la minuterie à quelle fréquence vous voulez le faire. TimerTask task = new TimerTask() {
@Override
public void run() {
//do some processing
}
};
Timer timer = new Timer();
timer.schedule(task, 0l, 1000l); //call the run() method at 1 second intervals
C'est probablement la solution la plus facile à suivre. La solution exécutante de John W est peut-être un peu plus mature.
Cette solution résoudra-t-elle réellement le problème de la rupture de l'OP à une certaine période?
+1 - Je me demandais également s'il résout le problème. Mais je suppose que cela fait si vous appelez Timer.Cancel () lorsque vous souhaitez que la minuterie s'arrête.
Dunno! (Si c'est ce qu'il veut), c'est comme ça que "briser une certaine heure et courir à nouveau" me lire, et il n'est jamais revenu pour clarifier, donc nous ne saurions jamais savoir.
En supposant que vous exécutez sur JDK 1.5 ou plus récent (où le modèle de mémoire a été clarifié et amélioré), vous pouvez utiliser alternativement, utilisez java.util.concurrent.future et futuetask, qui soutient l'annulation de la boîte. p> p>
Pourquoi avez-vous besoin de volatile pour la variable d'arrêt? Pour ce cas, je pense que c'est correct pour ne pas utiliser volatile ou se synchroniser là-bas?
@MDMA - Vous devriez utiliser le thread.Interrupt pour faire ce genre de chose. Par exemple, si dostuff () code> est un appel de blocage ou io appel, alors interruption () code> débloquera-le, mais votre approche ne sera pas.
Je pense que cela dépend simplement de savoir si vous voulez vraiment débloquer ou simplement attendre qu'il finit à obtenir des données IO et à courir à la prochaine boucle
@Stephen, vous avez raison, dans certains cas, à l'aide d'une interruption vous obtient ce que vous voulez, surtout si vous bloquez vraiment E / S, par exemple. Socket lit ou attend un événement. Il existe au moins 3 façons de coder les boucles annulables: drapeau volatil, drapeau synchronisé, interruptions explicites et chèques d'isinterrupted, et à l'aide de futuretask, mais plutôt que de nuire au problème avec trop d'exemples, je pensais qu'il est plus simple d'illustrer le cas général et de se référer À FutureTask pour d'autres besoins, qui a un drapeau iScancléd et gère des interruptions.
Et puis vous avez besoin de logique avec une tâche de minuterie pour appeler Annuler (), rejoindre le fil et redémarrer la boucle, oui?
@Vodkhang - Vous avez besoin d'une volatilité ou synchronisée. Si vous n'en avez pas d'autre, le fil principal d'exécution peut lire le drapeau une seule fois et lire chaque contrôle ultérieur du drapeau du cache. L'utilisation de volatils ou synchronisée assure la valeur mise en cache est ignorée. La volatilité est préférée dans ce cas simple, car elle évite la synchronisation des frais généraux.
@Cperkins - Peut-être - l'OP est un peu incertain sur ses besoins EACT - il n'est pas clair si une interruption / redémarrage régulière est nécessaire ou une fois / deux fois éteint, mais elles peuvent être gérées en tant que minuteries. Les minuteries sont discutées dans la première réponse pour que je puisse répéter cela.
@MDMA - a du sens, il suffit de répéter quelque part près de la réponse donnée.
Je pense que nous manquons des exécuteurs!
Il existe un planificateurExecutetorsservice que vous pouvez utiliser pour exécuter une tâche, puis exécuté à nouveau après une durée déterminée. Sa semblable à la clé de l'heure mais plus facile à gérer et mieux entretenue. P> L'exécuteur sera scheudle cette tâche chaque fois chaque seconde et peut également renvoyer une planification programmée que vous pouvez utiliser pour annuler ou annuler ou Obtenez le résultat (si vous utilisez un appelable à la place de Runnable). p> EDIT: Les CPERKINS apportent un bon point. Comment annulons-nous après une certaine quantité de temps puis réalisée. C'est un peu beaucoup mais ça fait le travail, je pense. P>
Non, cela ne la programmera pas chaque b> second ... Lisez les docs à nouveau :)
Ugh ... J'ai édité une fois pour utiliser la bonne API mais je ne l'ai pas envoyée! Merci
et pouvez-vous donner votre code..Parce que nous n'avons aucune idée de ce que cela pourrait être;)
Il est impossible de savoir ce que vous demandez réellement. S'il vous plaît fournir plus de détails.