2010-02-13 11 views
90

J'ai une fonction spécifique que je veux exécuter après 5 secondes. Comment puis-je faire cela en Java?java: exécute une fonction après un certain nombre de secondes

J'ai trouvé javax.swing.timer, mais je ne comprends pas vraiment comment l'utiliser. On dirait que je cherche quelque chose de plus simple que ce que cette classe propose.

Veuillez ajouter un exemple d'utilisation simple.

+0

Voulez-vous attendre 5 secondes, puis exécuter quelque chose ou voulez-vous continuer à faire autre chose dans les 5 secondes? – whiskeysierra

+0

Je veux continuer à faire autre chose – ufk

Répondre

153
new java.util.Timer().schedule( 
     new java.util.TimerTask() { 
      @Override 
      public void run() { 
       // your code here 
      } 
     }, 
     5000 
); 

EDIT:

javadoc dit:

Après la dernière référence en direct à un objet Timer disparaît et toutes les tâches en suspens ont terminé l'exécution, le thread d'exécution des tâches de la minuterie se termine avec élégance (et devient sujet à la collecte des ordures). Cependant, cela peut prendre arbitrairement longtemps.

+1

Si vous exécutez ce code, vous ferez des threads. Assurez-vous de nettoyer la minuterie lorsque vous avez terminé. – skaffman

+0

@skaffman: J'ai ajouté une instruction du javadoc. Avez-vous vraiment besoin de nettoyer après avoir appelé l'horaire? – tangens

+0

C'est peut-être OK, mais ce n'est peut-être pas le cas. Si vous exécutez ce fragment de code plusieurs fois, vous aurez des threads lâches sans aucun moyen de les ranger. – skaffman

39

Quelque chose comme ceci:

// When your program starts up 
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 

// then, when you want to schedule a task 
Runnable task = ....  
executor.schedule(task, 5, TimeUnit.SECONDS); 

// and finally, when your program wants to exit 
executor.shutdown(); 

Il existe plusieurs autres méthodes d'usine sur Executor que vous pouvez utiliser à la place, si vous voulez plus de fils dans la piscine.

Et rappelez-vous, il est important d'éteindre l'exécuteur lorsque vous avez terminé. La méthode shutdown() arrêtera proprement le pool de threads lorsque la dernière tâche sera terminée et bloquera jusqu'à ce que cela se produise. shutdownNow() terminera le pool de threads immédiatement.

5

vous pouvez utiliser la fonction Thread.Sleep()

Thread.sleep(4000); 
myfunction(); 

Votre fonction exécutera au bout de 4 secondes. Cependant, cela peut mettre en pause l'ensemble du programme ...

+15

Il mettra en pause le thread en cours, pas tout le programme. – skaffman

+0

Ouais, ofcourse :) – dale

+0

Et il garantit seulement que l'exécution se déroulera après 4sec, ce qui pourrait signifier après 10 sec aussi bien! – questzen

3

Votre question d'origine mentionne le "Swing Timer". Si en fait votre question est liée à SWing, alors vous devriez utiliser le temporisateur d'oscillation et pas le util.Timer.

Lisez la section du tutoriel Swing sur "How to Use Timers" pour plus d'informations.

20

Exemple d'utilisation javax.swing.Timer

Timer timer = new Timer(3000, new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent arg0) { 
    // Code to be executed 
    } 
}); 
timer.setRepeats(false); // Only execute once 
timer.start(); // Go go go! 

Ce code ne sera exécutée une fois, et l'exécution passe à 3000 ms (3 secondes). Comme le mentionne camickr, vous devriez chercher "How to Use Swing Timers" pour une brève introduction.

5

Mon code est le suivant:

new java.util.Timer().schedule(

    new java.util.TimerTask() { 
     @Override 
     public void run() { 
      // your code here, and if you have to refresh UI put this code: 
      runOnUiThread(new Runnable() { 
        public void run() { 
          //your code 

         } 
        }); 
     } 
    }, 
    5000 
); 
1

ScheduledThreadPoolExecutor a cette capacité, mais il est tout à fait lourd.

Timer a également cette capacité mais ouvre plusieurs threads même s'il n'est utilisé qu'une seule fois.

Voici une implémentation simple avec un test (signature près de Handler.postDelayed() Android):

public class JavaUtil { 
    public static void postDelayed(final Runnable runnable, final long delayMillis) { 
     final long requested = System.currentTimeMillis(); 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while (true) { 
        try { 
         long leftToSleep = requested + delayMillis - System.currentTimeMillis(); 
         if (leftToSleep > 0) { 
          Thread.sleep(leftToSleep); 
         } 
         break; 
        } catch (InterruptedException ignored) { 
        } 
       } 
       runnable.run(); 
      } 
     }).start(); 
    } 
} 

Test:

@Test 
public void testRunsOnlyOnce() throws InterruptedException { 
    long delay = 100; 
    int num = 0; 
    final AtomicInteger numAtomic = new AtomicInteger(num); 
    JavaUtil.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      numAtomic.incrementAndGet(); 
     } 
    }, delay); 
    Assert.assertEquals(num, numAtomic.get()); 
    Thread.sleep(delay + 10); 
    Assert.assertEquals(num + 1, numAtomic.get()); 
    Thread.sleep(delay * 2); 
    Assert.assertEquals(num + 1, numAtomic.get()); 
} 
+0

il donne avertissement sommeil appelé dans une boucle – shareef

1
Public static timer t; 

public synchronized void startPollingTimer() { 
     if (t == null) { 
      TimerTask task = new TimerTask() { 
       @Override 
       public void run() { 
        //Do your work 
       } 
      }; 

      t = new Timer(); 
      t.scheduleAtFixedRate(task, 0, 1000); 
     } 
    } 
+1

Alors que ce code peut répondre à la question, fournissant un contexte supplémentaire concernant pourquoi et/ou comment ce code répond à la question améliore sa valeur à long terme. – Mateus

0

En variante de @tangens réponse: si vous le pouvez » t attendez que le garbage collector nettoie votre thread, annulez le timer à la fin de votre méthode d'exécution.

Timer t = new java.util.Timer() 
    t.schedule( 
      new java.util.TimerTask() { 
       @Override 
       public void run() { 
        // your code here 
        // close the thread 
        t.cancel() 
       } 
      }, 
      5000 
    ); 
Questions connexes