2012-10-29 16 views
9

Próbuję uruchomić linię kodu co sekundę przy użyciu System.currentTimeMillis() ;.Uruchamiaj kod co sekundę, używając System.currentTimeMillis()

Kod:

 while(true){ 
      long var = System.currentTimeMillis()/1000; 
      double var2 = var %2; 

      if(var2 == 1.0){ 

       //code to run 

      }//If(): 

     }//While 

Kod, który chcę uruchomić, działa wiele razy ponieważ var2 jest ustawiony na 1,0 kilka razy ze względu na nieskończoną całej pętli. Po prostu chcę uruchomić linię kodu, gdy var2 jest najpierw ustawiony na 1.0, a następnie za każdym razem ponownie, gdy var2 staje się 1.0 po 0,0.

+1

Naprawdę powinienem zacząć zamieszczać komentarze na temat pętli i decyzji, takich jak Ty. Dobra robota za to. – Andy

+1

@Andy - proszę nie dodawać komentarzy do nawiasów zamykających w ten sposób.Użyj swojego IDE "pokaż pasujące nawiasy" i/lub zmień kod, tak abyś nie miał bloków, które są tak długie, że * potrzebujesz *, aby to zrobić. –

+0

@StephenC, myślę, że Andy był sarkastyczny. Jego komentarz nie był zbyt pomocny dla PO. –

Odpowiedz

14

Jeśli chcesz zająć się oczekiwaniem na zmianę sekund, możesz skorzystać z poniższego.

long lastSec = 0; 
while(true){ 
    long sec = System.currentTimeMillis()/1000; 
    if (sec != lastSec) { 
     //code to run 
     lastSec = sec; 
    }//If(): 
}//While 

Bardziej skutecznym podejściem jest spać do następnej sekundy.

while(true) { 
    long millis = System.currentTimeMillis(); 
    //code to run 
    Thread.sleep(1000 - millis % 1000); 
}//While 

Alternatywą jest użycie ScheduledExecutorService

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(); 

ses.scheduleAtFixedRate(new Runnable() { 
    @Override 
    public void run() { 
     // code to run 
    } 
}, 0, 1, TimeUnit.SECONDS); 

// when finished 
ses.shutdown(); 

Zaletą tego podejścia jest to, że

  • można mieć szereg zadań z różnych okresów dzielących ten sam wątek.
  • możesz mieć nie powtarzające się opóźnienia lub zadania asynchroniczne.
  • możesz zebrać wyniki w innym wątku.
  • można zamknąć pulę wątków za pomocą jednego polecenia.
+0

. Dzięki temu skorzystałem z pierwszej opcji, którą podałeś – Human

+0

+1 dla usługi Zaplanowane wykonanie usługi. – Twinone

2

Powinieneś używać klasy java.util.Timer i java.util.TimerTask.

+2

Jeśli kod nie znajduje się w wątku UI (z oczywistych względów), może również użyć Thread.sleep – Igor

+2

Funkcje API starszego timera i timera są okropne. Nie ma żadnego rozsądnego sposobu obsługi wyjątków i po wystąpieniu wyjątku cały wątek z timerem zostaje zabity. Musisz go ponownie uruchomić. Jest również wrażliwy na zmiany w zegarze systemowym, musisz odciążyć zegar systemowy (i wyłączyć DST!). Nowoczesny interfejs API do współbieżnego oprogramowania wykonawczego java util nie ma tych szczególnych problemów. – BalusC

1

Korzystanie z Thread.sleep(); byłoby idealne dla twojej sprawy.

while(true) 
{ 
    Thread.sleep(1000); // Waiting before run. 
    // Actual work goes here. 
} 
+0

To nie działa co sekundę. To czeka jedną sekundę po zakończeniu. Sam przebieg niekoniecznie zajmuje 0 sekund. Wyobraźmy sobie, że bieg trwa 200 ms, a następnie powinien faktycznie czekać 800 ms. Zamiast tego należy użyć usługi wykonawczego executora java util. – BalusC

+0

dziękuję, ale nie chcę zatrzymywać głównej klasy Java co sekundę. Jakikolwiek sposób to zrobić z System.currentTimemillis? – Human

+0

@BalusC masz rację. ale ta odpowiedź jest tylko po to, by dać napiwek OP. powinien skonfigurować czas snu. – Juvanis

3

Chciałbym używać bibliotek java executor. Możesz utworzyć ScheduledPool, który będzie działał i będzie działał przez dowolny okres czasu. Na przykład:

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new MyRunnable(), 0, 5, TimeUnit.SECONDS); 

Będzie prowadzić klasę MyRunnable co 5 sekund. MyRunnable musi implementować Runnable. Problem polega na tym, że za każdym razem (efektywnie) stworzy nowy wątek, który może być pożądany lub nie.

+0

Nie tylko tworzenie nowego wątku, ale także nowej puli wątków o wartości 1. – Nick

1

preferowany sposób:

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 

Następnie przechodzą w Runnables jak:

scheduler.scheduleWithFixedDelay(myRunnable, initDelay, delay, TimeUnit.MILLISECONDS); 

nie będę korzystać z programatora. Harmonogramy są budowane w celu obsługi problemów, które mogą powodować czasomierze. Ponadto wątek.sleep jest dobry dla prostego programu, który szybko piszesz w celu sprawdzenia typu koncepcji, ale nie używałbym go w świecie biznesu.

Powiązane problemy