2010-12-28 21 views
68

Próbowałem niektóre kody do wykonania zaplanowanego zadania i wymyśliłem te kody.Jak zaplanować uruchamianie zadania w okresowych odstępach czasu?

import java.util.*; 

class Task extends TimerTask { 


    int count = 1; 

    // run is a abstract method that defines task performed at scheduled time. 
    public void run() { 
     System.out.println(count+" : Mahendra Singh"); 
     count++; 
    } 
} 

class TaskScheduling { 

    public static void main(String[] args) { 
     Timer timer = new Timer(); 


     // Schedule to run after every 3 second(3000 millisecond) 
     timer.schedule(new Task(), 3000); 
    } 
} 

Moja wyjściowa:

1 : Mahendra Singh 

Spodziewałem kompilatora, aby wydrukować serię Mahendra Singh w okresowym odstępie 3 s ale mimo oczekiwania na około 15 minut, mam tylko jedno wyjście ... Jak mogę to rozwiązać?

+0

** Planer kwarcowy **, aby pomóc aplikacji Java zaplanować zadanie/zadanie do uruchomienia o określonej dacie i godzinie [sprawdź pełny przykład] (http://geekonjava.blogspot.com/2015/05/how -to-scheduling-job-in-java-via.html) – GeekOnJava

Odpowiedz

58

Użyj timer.scheduleAtFixedRate

public void scheduleAtFixedRate(TimerTask task, 
           long delay, 
           long period) 

harmonogramów określonego zadania do wielokrotnego wykonywania stałym oprocentowaniu, rozpoczynający się po określonym opóźnieniem. Kolejne egzekucje odbywają się w przybliżeniu w regularnych odstępach czasu, oddzielonych określonym czasem.
W przypadku realizacji o stałej szybkości każde wykonanie jest zaplanowane względem zaplanowanego czasu wykonania początkowego wykonania. Jeśli wykonanie zostanie opóźnione z jakiegokolwiek powodu (takiego jak zbieranie śmieci lub inna aktywność w tle), dwa lub większa liczba egzekucji będzie następować szybko po "nadrobieniu". W dłuższej perspektywie częstotliwość wykonywania będzie dokładnie odwrotnością określonego okresu (przy założeniu, że zegar systemowy leżący u podstaw Object.wait (long) jest dokładny).

Wykonanie stałej stawki jest odpowiednie dla powtarzających się czynności, które są wrażliwe na czas bezwzględny, takich jak dzwonienie dzwonka co godzinę na godzinę lub wykonywanie zaplanowanej konserwacji każdego dnia o określonej godzinie. Jest to również wskazane w przypadku powtarzających się czynności, w których ważny jest całkowity czas wykonania określonej liczby wykonań, takich jak zegar odliczający, który tyka raz na sekundę przez dziesięć sekund. Wreszcie, wykonanie o stałej stopie jest odpowiednie do planowania wielu powtarzających się zadań czasowych, które muszą pozostać zsynchronizowane względem siebie.

Parametry:

  • zadanie - zadanie być zaplanowane.
  • opóźnienie - opóźnienie w milisekundach, zanim zadanie ma zostać wykonane.
  • okres - czas w milisekundach między kolejnymi wykonaniami zadania.

Rzuty:

  • IllegalArgumentException - jeżeli opóźnienie jest ujemna lub opóźnienie + System.currentTimeMillis() jest ujemna.
  • IllegalStateException - jeśli zadanie zostało już zaplanowane lub anulowane, timer został anulowany lub wątek zakończy się.
+3

scheduleAtFixedRate nie rozwiązuje problemu z uzyskaniem wyniku tylko raz. –

+0

@ JamesA.N.Stauffer, potrzebuje on wyjścia wielokrotnie, ani razu. – st0le

+1

Tak, ale powtórzenie uzyskuje się po prostu przez dodanie trzeciego argumentu - zmiana metody nie jest potrzebna. –

12
public void schedule(TimerTask task,long delay) 

Planuje określone zadanie do wykonania po określonym opóźnieniu.

chcesz:

public void schedule(TimerTask task, long delay, long period) 

harmonogramy określone zadanie wielokrotnym czas opóźnienia realizacji, począwszy od określonego czasu. Kolejne egzekucje odbywają się w przybliżeniu w regularnych odstępach czasu oddzielonych określonym okresem.

3

Można użyć Quartz

+20

-1 Jeszcze jedna biblioteka potrzebna do podstawowego zadania, które można wykonać przy użyciu istniejącej struktury. tak kwarc może zrobić więcej, ale nie jest pomocny w kontekście tego pytania. – JDC

+2

@JDC: Po co wyważać koło? –

+0

Zgadzam się z powyższymi komentarzami, ale powiedziałbym, że nadal będzie to odpowiedź OK, jeśli poda przykład. Reguły SO twierdzą, że link nie jest odpowiedzią. To powinien być komentarz. –

65

ScheduledExecutorService

Pragnę zaoferować alternatywę dla timera przy użyciu - ScheduledThreadPoolExecutor, implementacja interfejsu ScheduledExecutorService. Ma pewne zalety w stosunku do klasy Timer (od "Java in Concurrency"):

Timer tworzy tylko jeden wątek do wykonywania zadań czasomierza. Jeśli wykonanie zadania timera trwa zbyt długo, może to mieć wpływ na dokładność taktowania innych TimerTasks. Jeśli powtarzająca się funkcja TimerTask ma być uruchamiana co 10 ms, a inna funkcja Timer-Task trwa 40 ms, cykliczne zadanie (w zależności od tego, czy zostało zaplanowane ze stałą szybkością lub stałym opóźnieniem), jest wywoływane cztery razy w krótkim odstępie czasu po długim czasie. - uruchamianie zadania kończy się lub "pomija" cztery inwokacje całkowicie. Zaplanowane pule wątków rozwiązują to ograniczenie, umożliwiając udostępnienie wielu wątków do wykonywania zadań odroczonych i okresowych.

Innym problemem z Timerem jest to, że zachowuje się źle, jeśli TimerTask rzuca niesprawdzony wyjątek. Wątek Timer nie przechwytuje wyjątku, więc niezaznaczony wyjątek zgłoszony przez TimerTask kończy wątek timera. Timer również nie wskrzesza nici w tej sytuacji; zamiast tego błędnie zakłada się, że cały Timer został anulowany. W takim przypadku TimerTasks, które są już zaplanowane, ale jeszcze nie zostały wykonane, nigdy nie są uruchamiane, a nowych zadań nie można zaplanować. (Ten problem, zwany "wyciekiem nici").

I inne zalecenia, jeśli chcesz zbudować własną usługę planowania, nadal możesz być w stanie skorzystać z biblioteki za pomocą DelayQueue, implementacja BlockingQueue, która zapewnia funkcje planowania ScheduledThreadPoolExecutor. DelayQueue zarządza zbiorem opóźnionych obiektów. Opóźnienie ma powiązany z nim czas opóźnienia: DelayQueue pozwala ci wziąć element tylko wtedy, gdy upłynął jego czas opóźnienia. Obiekty są zwracane z DelayQueue zamówionego przez czas związany z ich opóźnieniem.

+2

Kolejny problem z timerem polega na tym, że przy zmianie zegara systemowego, komunikator z timerem – rajath

0

W tym celu Java ma klasę Timer i TimerTask, ale co to jest?

  • java.util.Timer jest klasa narzędzie, które może być wykorzystywane w celu planowania gwint być wykonywane w pewnym czasie w przyszłości. Klasa Timer Java może służy do planowania zadań uruchamianych jednorazowo lub do regularnych interwałów .
  • java.util.TimerTask jest klasą abstrakcyjną, która implementuje Runnable interfejs i musimy rozszerzyć tę klasę tworzyć własne TimerTask które mogą być zaplanowane z wykorzystaniem klasy Java Timer.

Można sprawdzić pełną samouczek z GeekonJava

TimerTask timerTask = new MyTimerTask(); 

//running timer task as daemon thread 

Timer timer = new Timer(true); 

timer.scheduleAtFixedRate(timerTask, 0, 10*1000); 
3

Quartz scheduler jest również rozwiązanie, a przede wszystkim zrobić klasę Quartz Job.

Quartz praca definiuje co chcesz uruchomić

package com.blogspot.geekonjava.quartz; 
import org.quartz.Job; 
import org.quartz.JobExecutionContext; 
import org.quartz.JobExecutionException; 
import org.quartz.JobKey; 
public class QuartzJob implements Job { 
     public void execute(JobExecutionContext context) 
         throws JobExecutionException { 
       JobKey jobKey = context.getJobDetail().getKey(); 
       System.out.println("Quartz" + "Job Key " + jobKey); 
     } 
} 

Teraz trzeba dokonać Quartz spust

Istnieją dwa rodzaje wyzwalaczy w Quartz

SimpleTrigger - Pozwala ustawić czas rozpoczęcia, czas zakończenia, przedział powtórzeń.

Trigger trigger = newTrigger().withIdentity("TriggerName", "Group1") 
       .withSchedule(SimpleScheduleBuilder.simpleSchedule() 
       .withIntervalInSeconds(10).repeatForever()).build(); 

CronTrigger - Pozwala Unix cron wyraz określić daty i razy, aby uruchomić zadanie.

Trigger trigger = newTrigger() 
       .withIdentity("TriggerName", "Group2") 
       .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")).build(); 

linki klasy Scheduler zarówno Praca i wyzwalania razem i wykonać ją.

Scheduler scheduler = new StdSchedulerFactory().getScheduler(); 
scheduler.start(); 
scheduler.scheduleJob(job, trigger); 

Full Example you can see here

1

timer.scheduleAtFixedRate (nowe zadania(), 1000,3000);

Powiązane problemy