2010-08-17 3 views
2

J'ai une question sur le comportement de la classe Timer en Java. Voici le code: « Oui » http://pastebin.com/mqcL9b1nTimerTask continue à fonctionner

public class Main { 

    public static void main(String[] args) { 
     Main m = new Main(); 
     m.foo(); 
     m = null; 
    } 

    public void foo() 
    { 
     Timer t = new Timer(); 
     t.schedule(new SysPrint(), 200); 
    } 

} 

class SysPrint extends TimerTask 
{ 
    public void run() 
    { 
     System.out.println("Yes!"); 
    } 
} 

Ce qui se passe est que si vous exécutez ce programme, il imprimera et ça ne va rien faire d'autre (le programme ne se termine pas). La documentation Java dit: Après que la dernière référence en direct à un objet Timer disparaît et que toutes les tâches en attente ont été exécutées, le thread d'exécution de tâche du temporisateur se termine normalement (et devient sujet à la récupération de place). Comme je vois cette chose, la "dernière référence en direct" à l'objet Timer est allée après la fin des fonctions 'foo()'. Et la seule tâche prévue était le "Oui!" tâche qui a été exécutée, donc je suppose que, après que le processus a imprimé "Oui!", l'objet Timer devrait se terminer et le processus devrait se terminer.

Que s'est-il passé ici?

+0

Jetez un oeil à la ScheduledExecutorService –

Répondre

2

Java ne se termine pas car votre thread exécutant le Timer continue de tourner. Vous devez marquer ce thread comme étant un thread démon avant que Java ne sorte. Vous n'avez probablement pas accès au thread lui-même, à moins que Timer n'ait une méthode pour le marquer, donc vous aurez du mal à le faire. Vous devrez l'arrêter manuellement dans une clause finally.

try { 
    timer = new Timer(); 
    timer.schedule(new SysPrint(), 200); 
} finally { 
    timer.cancel(); 
} 
+0

Je pense que ce n'est pas une réponse à ma question. Cela ne fonctionne même jamais le "Oui!" imprimer peut-être. Il planifie, puis annule le fil. – makakko

+0

@makakko: au lieu d'appeler la méthode 'cancel()' dans 'main()', appelez la méthode 'TimerTask.cancel()' depuis votre méthode 'SysPrint.run()'. –

+0

comme expliqué dans javavdoc, vous devez appeler cancel après l'exécution de votre tâche: "Après la fin de la dernière référence en direct à un objet Timer et que toutes les tâches en attente ont été exécutées, le thread d'exécution de la tâche s'arrête normalement (et devient garbage collection) Cependant, le thread d'exécution de la tâche ne peut pas être exécuté en tant que thread de démon, il est donc capable d'empêcher une application de se terminer.Si un appelant veut mettre fin à l'exécution d'une tâche du timer thread rapidement, l'appelant devrait invoquer la méthode d'annulation du timer. " – crafty

Questions connexes