Pause/arrêt et démarrage/reprise de Java TimerTask en continu?
J'ai une question simple concernant Java TimerTask. Comment puis-je mettre en pause/reprendre deux TimerTask des tâches en fonction d'un certain état? Par exemple, j'ai deux minuteries qui courent entre les uns des autres. Lorsqu'une certaine condition a été remplie à l'intérieur de la tâche de première minuterie, la minuterie d'abord s'arrête et commence la deuxième timer, et la même chose se produit lorsqu'une certaine condition a été remplie à l'intérieur de la tâche de deuxième timer. La classe ci-dessous montre exactement ce que je veux dire:
public class TimerTest {
Timer timer1;
Timer timer2;
volatile boolean a = false;
public TimerTest() {
timer1 = new Timer();
timer2 = new Timer();
}
public void runStart() {
timer1.scheduleAtFixedRate(new Task1(), 0, 1000);
}
class Task1 extends TimerTask {
public void run() {
System.out.println("Checking a");
a = SomeClass.getSomeStaticValue();
if (a) {
//Pause/stop timer1, start/resume timer2 for 5 seconds
timer2.schedule(new Task2(), 5000);
}
}
}
class Task2 extends TimerTask{
public void run() {
System.out.println("Checking a");
a = SomeClass.getSomeStaticValue();
if (!a) {
//Pause/stop timer2, back to timer1
timer1.scheduleAtFixedRate(new Task1(), 0, 1000);
}
//Do something...
}
}
public static void main(String args[]) {
TimerTest tt = new TimerTest();
tt.runStart();
}
}
Donc ma question est, comment puis-je mettre en pause timer1
lors de l'exécution de timer2
et vice-versa, tandis que timer2
est en cours d'exécution? Les performances et le calendrier est ma principale préoccupation est que ce doit être mise en œuvre à l'intérieur d'un autre thread en cours d'exécution. Par la façon dont je suis en train de mettre en œuvre ces simultanées des minuteries sur Android.
Merci pour votre aide!
- Quel est l'exception?
- Exception in thread "Timer 1" de java.lang.IllegalStateException: Minuterie déjà annulé.
- Vous voudrez peut-être penser le déplacement de plus de
java.util.concurrent
.Timer
est considéré comme un peu de la vieille école. - J'ai édité à partir de l'arrêt/redémarrage de suspendre/reprendre les compteurs à zéro. Est-il possible à l'aide de
Thread.sleep(milliseconds)
? - Je réalise que c'est juste un exemple de code et vous êtes sur de plus grandes choses. Mais dans cet exemple, vous ne devez pas utiliser deux minuteries, mais, avec appropriée si les conditions de dicter le comportement à faire à l'intérieur de la méthode run. De nombreuses fois on pense au nombre de minuteries et de nombreux TimerTasks, quand vous n'avez besoin que si vous avez obtenu une sorte de périodicité que l'exige (l'un est de 20ms, un autre est toutes les 2 minutes). Même dans ce cas, je ne voudrais pas mettre en pause, comme je le dis dans ma réponse. Je voudrais juste changer ce que la méthode run n'. À moins, bien sûr, ils font quelque chose qui est à la fois sensible (par exemple, l'exécution d'un chronographe).
- Tom Hawtin, comment est-Minuterie de la vieille école? J'ai vu des gens se battre avec fil basés sur des concepts de résoudre en temps réel les problèmes qui peuvent être résolus facilement avec des minuteries. À rebours est bel et bien vivant, et les fils sont grands pour le filetage.
- Je veux effectuer deux tâches différentes basée sur une seule condition à différents taux. Par exemple, disons
timer1
vérifiea
pour chaque seconde et sia
est vrai, alorstimer2
commence à se produire quelque chose pendant 5 secondes, s'arrête et poursuivre la vérificationa
pour chaque seconde. - J'ai ré-édité de nouveau le code étroitement montrer exactement ce que je suis en train de faire. Désolé pour la confusion!
- c'est clair. Mon point est que même avec des périodicités différentes -- 5 secondes et 2 secondes, je voudrais juste prévoir deux à taux fixe des tâches sur un minuteur. Sauf si c'est absolument vital que les autres minuterie commencer à compter les secondes à PARTIR de QUAND IL EST allumé. Si non, vous avez juste garder les tâches en cours d'exécution et ne modifient que leurs exécuter des méthodes.
Vous devez vous connecter pour publier un commentaire.
De
TimerTask.annuler()
:Donc, une fois annulée, elle ne sera jamais fonctionner à nouveau. Vous seriez mieux au lieu d'utiliser la plus moderne
ScheduledExecutorService
(à partir de Java 5+).Edit: Le concept de base est:
mais la recherche en elle il n'y a aucun moyen d'annuler cette tâche une fois sa main sans la fermeture du service, qui est un peu bizarre.
TimerTask
pourrait être plus facile dans ce cas, mais vous aurez besoin de créer une nouvelle instance lorsque vous démarrez un. Il ne peut pas être réutilisée.Sinon, vous pouvez encapsuler chaque tâche séparément transitoire de service:
ScheduledExceutorService
dans la classe ci-dessus? mercicancel(false)
ne sera passolution la plus simple que j'ai trouvé: il suffit d'ajouter un booléen dans le code d'exécution dans le timer de la tâche, comme suit:
Si vous avez déjà annulé une minuterie, vous ne pouvez pas re-démarrer, vous devrez en créer un nouveau.
Voir ce réponse, il contient une vidéo et le code source comment j'ai fait quelque chose de similaire.
Fondamentalement, il existe deux méthode:
pause
etresume
En pause:
En résumé:
Qui rend la perception de la mettre en pause/reprendre.
Si votre minuteries d'effectuer différentes actions en fonction de l'état de l'application vous pouvez envisager d'utiliser le StatePattern
Poing définir un résumé de l'état:
Et autant de membres que vous le souhaitez. La clé est qu'un état amène à un autre.
Et que vous modifiez l'état de votre minuterie.
Enfin, si ce que vous avez besoin est d'effectuer la même chose, mais à des taux différents, vous pouvez envisager d'utiliser le TimingFramework. C'est un peu plus complexe, mais vous ne les animations superbes, en permettant à la peinture de certains composants lieu à des taux différents ( au lieu d'être linéaire )
À mon avis, c'est quelque peu erronée. Si votre code doit garanties de temps, vous ne pouvez pas utiliser la Minuterie de toute façon, ni voulez-vous. "Cette classe n'a pas d'offre en temps réel de garanties: il planifie les tâches à l'aide de l'Objet.attendre(longtemps) de la méthode."
La réponse, à mon humble avis, c'est que vous ne voulez pas mettre en pause et redémarrer votre minuteries. Vous voulez juste de supprimer leurs exécuter des méthodes de faire de leur entreprise. Et c'est facile: il suffit de les envelopper dans un
if
déclaration. Le commutateur est sur, ils courent, l'interrupteur est sur off, ils ratent ce cycle.Edit: La question a nettement changé de ce qu'il était à l'origine, mais je vais laisser cette réponse dans le cas où il peut aider n'importe qui. Mon point est: si vous n'avez pas de soins lors de votre événement se déclenche dans les N millisecondes span (juste qu'il ne DÉPASSE pas une fois toutes les N millisecondes), vous pouvez simplement utiliser le conditionnel sur l'exécution des méthodes. C'est, en fait, un cas très commun, surtout lorsque N est inférieur à 1 seconde.
De l'examen de votre code source, voici les changements ( qui assez bien valider ma réponse précédente )
Dans task1:
et dans task2:
Il fonctionne sur ma machine:
Android de ne pas réutiliser un TimerTask qui a déjà été programmée une fois. Il est donc nécessaire de retrouver à la fois la Minuterie et TimerTask, par exemple, comme ceci dans un Fragment:
Je suis en mesure d'arrêter une minuterie et d'une tâche à l'aide de code suivant: