java: esegue una funzione dopo un numero specifico di secondi

Ho una funzione specifica che voglio essere eseguita dopo 5 secondi. Come posso farlo in Java?

Ho trovato javax.swing.timer, ma non riesco davvero a capire come usarlo. Sembra che sto cercando qualcosa di più semplice di questa class.

Si prega di aggiungere un semplice esempio di utilizzo.

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

MODIFICARE:

javadoc dice:

Dopo che l’ultimo riferimento live a un object Timer scompare e tutte le attività in sospeso hanno completato l’esecuzione, il thread di esecuzione del task del timer termina con garbo (e diventa sobject alla procedura di Garbage Collection). Tuttavia, ciò può richiedere un tempo arbitrariamente lungo.

Qualcosa come questo:

 // 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(); 

Esistono vari altri metodi factory su Executor che è ansible utilizzare al contrario, se si desidera più thread nel pool.

E ricorda, è importante spegnere l’esecutore quando hai finito. Il metodo shutdown() interromperà in modo pulito il pool di thread al termine dell’ultima attività e bloccherà fino a quando ciò non si verifica. shutdownNow() interromperà immediatamente il pool di thread.

Esempio di utilizzo di javax.swing.Timer

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

Questo codice verrà eseguito una sola volta e l’esecuzione avviene in 3000 ms (3 secondi).

Come menzionato da Camickr, dovresti cercare ” Come usare i timer Swing ” per una breve introduzione.

Il mio codice è il seguente:

 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 ); 

La tua domanda iniziale menziona il “Timer Swing”. Se in realtà la tua domanda è correlata a SWing, allora dovresti usare il timer Swing e NON l’util.Timer.

Leggi la sezione dal tutorial Swing su ” Come usare i timer ” per maggiori informazioni.

potresti usare la funzione Thread.Sleep ()

 Thread.sleep(4000); myfunction(); 

La tua funzione verrà eseguita dopo 4 secondi. Tuttavia questo potrebbe mettere in pausa l’intero programma …

ScheduledThreadPoolExecutor ha questa capacità, ma è abbastanza pesante.

Timer ha anche questa capacità ma apre diversi thread anche se usati una sola volta.

Ecco una semplice implementazione con un test (firma vicina a Android’s Handler.postDelayed () ):

 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()); } 
 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); } } 

Come variante della risposta @tangens: se non riesci ad aspettare che il garbage collector pulisca la tua discussione, cancella il timer alla fine del tuo metodo di esecuzione.

  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 ); 

Tutti gli altri utenti inesperti richiedono l’esecuzione del codice all’interno di una nuova discussione. In alcuni casi di utilizzo semplice, potresti semplicemente aspettare un po ‘e continuare l’esecuzione all’interno dello stesso thread / stream.

Il codice qui sotto dimostra questa tecnica. Tieni presente che è simile a ciò che java.util.Timer fa sotto il cofano ma più leggero.

 import java.util.concurrent.TimeUnit; public class DelaySample { public static void main(String[] args) { DelayUtil d = new DelayUtil(); System.out.println("started:"+ new Date()); d.delay(500); System.out.println("half second after:"+ new Date()); d.delay(1, TimeUnit.MINUTES); System.out.println("1 minute after:"+ new Date()); } } 

DelayUtil Implementation

 import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class DelayUtil { /** * Delays the current thread execution. * The thread loses ownership of any monitors. * Quits immediately if the thread is interrupted * * @param duration the time duration in milliseconds */ public void delay(final long durationInMillis) { delay(durationInMillis, TimeUnit.MILLISECONDS); } /** * @param duration the time duration in the given {@code sourceUnit} * @param unit */ public void delay(final long duration, final TimeUnit unit) { long currentTime = System.currentTimeMillis(); long deadline = currentTime+unit.toMillis(duration); ReentrantLock lock = new ReentrantLock(); Condition waitCondition = lock.newCondition(); while ((deadline-currentTime)>0) { try { lock.lockInterruptibly(); waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } finally { lock.unlock(); } currentTime = System.currentTimeMillis(); } } }