Come pianificare un'attività periodica in Java?


183

Devo pianificare un'attività da eseguire a intervalli fissi di tempo. Come posso farlo con il supporto di lunghi intervalli (ad esempio ogni 8 ore)?

Attualmente sto usando java.util.Timer.scheduleAtFixedRate. Fa java.util.Timer.scheduleAtFixedRatelunghi intervalli di tempo di sostegno?

Risposte:


261

Utilizzare un servizio ScheduledExecutor :

 private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
 scheduler.scheduleAtFixedRate(yourRunnable, 8, 8, TimeUnit.HOURS);

1
Se vuoi che questo venga eseguito ogni giorno in un momento specifico non c'è un ottimo modo per farlo, perché TimeUnitvale sia per il initialDelayche per il period. La corsa ogni 24 ore finirà per essere espulsa quando DST inizia, ma un TimeUnitdi DAYSnon ti consente di specificare un grana fine initialDelay. (Penso che l'implementazione interna ScheduledExecutorService converta DAYScomunque in nanosecondi).
Sam Barnum,

46

Dovresti dare un'occhiata a Quartz , un framework Java che funziona con le versioni EE e SE e consente di definire i lavori da eseguire in un momento specifico


23

Prova in questo modo ->

In primo luogo creare un TimeTask di classe che esegua l'attività, sembra:

public class CustomTask extends TimerTask  {

   public CustomTask(){

     //Constructor

   }

   public void run() {
       try {

         // Your task process

       } catch (Exception ex) {
           System.out.println("error running thread " + ex.getMessage());
       }
    }
}

quindi nella classe principale si crea un'istanza dell'attività ed eseguirla periodicamente avviata entro una data specifica:

 public void runTask() {

        Calendar calendar = Calendar.getInstance();
        calendar.set(
           Calendar.DAY_OF_WEEK,
           Calendar.MONDAY
        );
        calendar.set(Calendar.HOUR_OF_DAY, 15);
        calendar.set(Calendar.MINUTE, 40);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);



        Timer time = new Timer(); // Instantiate Timer Object

        // Start running the task on Monday at 15:40:00, period is set to 8 hours
        // if you want to run the task immediately, set the 2nd parameter to 0
        time.schedule(new CustomTask(), calendar.getTime(), TimeUnit.HOURS.toMillis(8));
}

6
Per rendere il codice più leggibile, è possibile modificare l'argomento finale nella pianificazione della chiamata a TimeUnit.HOURS.toMillis (8)
darrenmc,

La documentazione per Timer consiglia invece di utilizzare il framework Executor.
Karan Khanna,

14

Utilizza Google Guava AbstractScheduledServicecome indicato di seguito:

public class ScheduledExecutor extends AbstractScheduledService
{
   @Override
   protected void runOneIteration() throws Exception
   {
      System.out.println("Executing....");
   }

   @Override
   protected Scheduler scheduler()
   {
        return Scheduler.newFixedRateSchedule(0, 3, TimeUnit.SECONDS);
   }

   @Override
   protected void startUp()
   {
       System.out.println("StartUp Activity....");
   }


   @Override
   protected void shutDown()
   {
       System.out.println("Shutdown Activity...");
   }

   public static void main(String[] args) throws InterruptedException
   {
       ScheduledExecutor se = new ScheduledExecutor();
       se.startAsync();
       Thread.sleep(15000);
       se.stopAsync();
   }

}

Se si dispone di più servizi come questo, la registrazione di tutti i servizi in ServiceManager sarà buona in quanto tutti i servizi possono essere avviati e arrestati insieme. Leggi qui per ulteriori informazioni su ServiceManager.


9

Se si desidera attenersi a java.util.Timer, è possibile utilizzarlo per pianificare a grandi intervalli di tempo. Passi semplicemente il periodo in cui stai sparando. Controlla la documentazione qui .


5

Queste due classi possono collaborare per pianificare un'attività periodica:

Operazione pianificata

import java.util.TimerTask;
import java.util.Date;

// Create a class extending TimerTask
public class ScheduledTask extends TimerTask {
    Date now; 
    public void run() {
        // Write code here that you want to execute periodically.
        now = new Date();                      // initialize date
        System.out.println("Time is :" + now); // Display current time
    }
}

Esegui attività pianificata

import java.util.Timer;

public class SchedulerMain {
    public static void main(String args[]) throws InterruptedException {
        Timer time = new Timer();               // Instantiate Timer Object
        ScheduledTask st = new ScheduledTask(); // Instantiate SheduledTask class
        time.schedule(st, 0, 1000);             // Create task repeating every 1 sec
        //for demo only.
        for (int i = 0; i <= 5; i++) {
            System.out.println("Execution in Main Thread...." + i);
            Thread.sleep(2000);
            if (i == 5) {
                System.out.println("Application Terminates");
                System.exit(0);
            }
        }
    }
}

Riferimento https://www.mkyong.com/java/how-to-run-a-task-periodically-in-java/


La migliore soluzione fino ad ora, più pulita e facile da implementare
Salvador Vigo,


4

Fai qualcosa ogni secondo

Timer timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        //code
    }
}, 0, 1000);

1
La documentazione per Timer consiglia invece di utilizzare il framework Executor
Karan Khanna,

3

Uso la funzionalità di Spring Framework. ( vaso contestuale primaverile o dipendenza maven).

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


@Component
public class ScheduledTaskRunner {

    @Autowired
    @Qualifier("TempFilesCleanerExecution")
    private ScheduledTask tempDataCleanerExecution;

    @Scheduled(fixedDelay = TempFilesCleanerExecution.INTERVAL_TO_RUN_TMP_CLEAN_MS /* 1000 */)
    public void performCleanTempData() {
        tempDataCleanerExecution.execute();
    }

}

Operazione pianificata è la mia interfaccia con il mio metodo personalizzato execute , che chiamo come attività pianificata.


2

Hai provato Spring Scheduler usando le annotazioni?

@Scheduled(cron = "0 0 0/8 ? * * *")
public void scheduledMethodNoReturnValue(){
    //body can be another method call which returns some value.
}

puoi farlo anche con xml.

 <task:scheduled-tasks>
   <task:scheduled ref = "reference" method = "methodName" cron = "<cron expression here> -or- ${<cron expression from property files>}"
 <task:scheduled-tasks>

0

il mio servlet contiene questo come codice come mantenerlo nello scheduler se un utente preme accetta

if(bt.equals("accept")) {
    ScheduledExecutorService scheduler=Executors.newScheduledThreadPool(1);
    String lat=request.getParameter("latlocation");
    String lng=request.getParameter("lnglocation");
    requestingclass.updatelocation(lat,lng);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.