2010-02-13 8 views
90

Mam określoną funkcję, którą chcę wykonać po 5 sekundach. Jak mogę to zrobić w Javie?java: uruchom funkcję po określonej liczbie sekund

Znalazłem javax.swing.timer, ale nie mogę zrozumieć, jak z niego korzystać. Wygląda na to, że szukam czegoś prostszego niż ta klasa zapewnia.

Dodaj prosty przykład zastosowania.

+0

Czy chcesz poczekać 5 sekund, a następnie wykonać coś lub chcesz kontynuować robienie czegoś innego w ciągu 5 sekund? – whiskeysierra

+0

Chcę dalej robić coś innego – ufk

Odpowiedz

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

EDIT:

javadoc mówi:

Po ostatnim żywo odwołanie do obiektu Timer odchodzi i wszystkie zaległe zadania zakończeniu realizacji, gwint wykonanie zadania timer kończy wdzięcznie (i staje się przedmiotem zbierania śmieci). Jednak może to zająć dość długo.

+1

Jeśli uruchomisz ten kod, spowodujesz wyciekanie wątków. Pamiętaj, aby wyczyścić timer po zakończeniu. – skaffman

+0

@skaffman: Dodałem oświadczenie z javadoc. Czy naprawdę musisz posprzątać po harmonogramie połączeń? – tangens

+0

Może być OK, ale może nie być. Jeśli wielokrotnie uruchamiasz ten fragment kodu, będziesz miał luźne wątki, które się nie kopią bez żadnego sprzątania. – skaffman

39

coś takiego:

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

Istnieją różne inne metody fabryki na Executor których można użyć zamiast tego, jeśli chcesz więcej wątków w basenie.

Pamiętaj, że ważne jest, aby zamknąć executor po zakończeniu. Metoda shutdown() spowoduje wyczyszczenie puli wątków po zakończeniu ostatniego zadania i zablokuje do tego czasu. shutdownNow() natychmiast zamknie pulę wątków.

5

można użyć funkcji Thread.Sleep()

Thread.sleep(4000); 
myfunction(); 

Twoja funkcja wykona po 4 sekundach. Może to jednak wstrzymać cały program ...

+15

Zatrzyma bieżący wątek, a nie cały program. – skaffman

+0

Tak, oczywiście :) – dale

+0

Gwarantuje to tylko, że wykonanie zostanie uruchomione po 4 sekundach, co może oznaczać również po 10 sekundach! – questzen

3

Twoje oryginalne pytanie wspomina o "zegarze obrotowym". Jeśli w rzeczywistości twoje pytanie jest związane z SWingiem, powinieneś używać Swing Timer a NIE the util.Timer.

Przeczytaj sekcję z samouczka Swinga na temat "How to Use Timers", aby uzyskać więcej informacji.

20

Przykład zastosowania 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! 

Kod ten będzie wykonywane tylko raz, a wykonanie dzieje w 3000 ms (3 sekundy).

Jak wspomina Camickr, powinieneś sprawdzić "How to Use Swing Timers", aby uzyskać krótkie wprowadzenie.

5

Mój kod wygląda następująco:

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 ma tę zdolność, ale to zupełnie wagi ciężkiej.

Timer również ma tę zdolność, ale otwiera kilka wątków, nawet jeśli są używane tylko raz.

Oto prosta implementacja z testu (podpis blisko Android 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()); 
} 
+0

daje ostrzeżenie o śnie wywołanym w pętli – 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

Podczas gdy ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, dlaczego i/lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość. – Mateus

0

Jako odmianę @tangens odpowiedzieć: jeśli możesz” • poczekaj, aż śmieciarz wyczyści swój wątek, anuluj licznik czasu na końcu metody uruchamiania.

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