Java'da periyodik bir görev nasıl zamanlanır?


183

Belirli bir zaman diliminde çalışacak bir görev zamanlamalıyım. Bunu uzun aralıklarla (örneğin her 8 saatte bir) destekleyerek nasıl yapabilirim?

Şu anda kullanıyorum java.util.Timer.scheduleAtFixedRate. java.util.Timer.scheduleAtFixedRateUzun zaman aralıklarını destekliyor mu ?

Yanıtlar:


261

ScheduledExecutorService kullanın :

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

1
Bunun her gün belirli bir saatte çalışmasını istiyorsanız, bunu yapmanın harika bir yolu yoktur, çünkü TimeUnithem initialDelayve hem de için geçerlidir period. DST devreye girdiğinde 24 saatte bir koşmak sona erer, ancak a TimeUnit, DAYSince taneli bir yöntem belirtmenize izin vermez initialDelay. (Bence dahili ScheduledExecutorService uygulaması DAYSnanosaniyeye dönüştürür zaten).
Sam Barnum

46

Sen bir göz atmalısınız Kuvars o EE ve SE sürümleri ile çalışır ve bir belirli bir saat çalıştırmak için işleri tanımlamanızı sağlar wich java çerçeve var


23

Bu şekilde deneyin ->

Öncelikle görevinizi yürüten bir sınıf TimeTask oluşturun, şöyle görünür:

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

ana sınıfta görevi başlatır ve belirli bir tarihte düzenli aralıklarla başlatırsınız:

 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
Kodu daha okunabilir hale getirmek için, TimeUnit.HOURS.toMillis (8)
darrenmc

Zamanlayıcı belgeleri bunun yerine Yürütücü çerçevesinin kullanılmasını önerir.
Karan Khanna

14

Google Guava'yı AbstractScheduledServiceaşağıda belirtildiği gibi kullanın :

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

}

Bunun gibi daha fazla hizmetiniz varsa, tüm hizmetler birlikte başlatılabileceği ve durdurulabileceği için ServiceManager'a tüm hizmetlerin kaydedilmesi iyi olacaktır. ServiceManager hakkında daha fazla bilgi için burayı okuyun .


9

Yapışmak istiyorsanız java.util.Timer, büyük zaman aralıklarında planlamak için kullanabilirsiniz. Sadece çekim yaptığınız dönemi geçersiniz. Buradaki belgelere bakın .


5

Bu iki sınıf, periyodik bir görevi zamanlamak için birlikte çalışabilir:

Planli gorev

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
    }
}

Zamanlanmış Görevi Çalıştır

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

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


Şimdiye kadarki en iyi çözüm, daha temiz ve uygulanması kolay
Salvador Vigo


4

Her saniyede bir şey yap

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

1
Timer belgeleri bunun yerine Yürütücü çerçevesinin kullanılmasını önerir
Karan Khanna

3

Spring Framework'ün özelliğini kullanıyorum. ( bahar bağlamı kavanoz veya maven bağımlılığı).

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

}

ScheduledTask , zamanlanmış görevim olarak adlandırdığım özel yöntem yürütme ile kendi arabirimdir.


2

Ek açıklamaları kullanarak Spring Scheduler'ı denediniz mi?

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

bunu xml ile de yapabilirsiniz.

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

0

benim sunucu uygulamam bunu bir kullanıcı olarak kabul ederse bunu zamanlayıcıda tutmayı bir kod olarak içerir

if(bt.equals("accept")) {
    ScheduledExecutorService scheduler=Executors.newScheduledThreadPool(1);
    String lat=request.getParameter("latlocation");
    String lng=request.getParameter("lnglocation");
    requestingclass.updatelocation(lat,lng);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.