web-dev-qa-db-ja.com

TimerTask 2を毎日実行する方法2 PM

毎日午後2時にジョブを実行します。 Java.util.Timerのどのメソッドを使用してジョブをスケジュールできますか?

2時間実行した後、ジョブを停止し、翌日の午後2時に再スケジュールします。

34
BOSS
import Java.util.Calendar;
import Java.util.Date;
import Java.util.GregorianCalendar;
import Java.util.Timer;
import Java.util.TimerTask;


public class MyTimerTask extends TimerTask {
    private final static long ONCE_PER_DAY = 1000*60*60*24;

    //private final static int ONE_DAY = 1;
    private final static int TWO_AM = 2;
    private final static int ZERO_MINUTES = 0;


    @Override
    public void run() {
        long currennTime = System.currentTimeMillis();
        long stopTime = currennTime + 2000;//provide the 2hrs time it should execute 1000*60*60*2
          while(stopTime != System.currentTimeMillis()){
              // Do your Job Here
            System.out.println("Start Job"+stopTime);
            System.out.println("End Job"+System.currentTimeMillis());
          }
    }
    private static Date getTomorrowMorning2AM(){

        Date date2am = new Java.util.Date(); 
           date2am.setHours(TWO_AM); 
           date2am.setMinutes(ZERO_MINUTES); 

           return date2am;
      }
    //call this method from your servlet init method
    public static void startTask(){
        MyTimerTask task = new MyTimerTask();
        Timer timer = new Timer();  
        timer.schedule(task,getTomorrowMorning2AM(),1000*10);// for your case u need to give 1000*60*60*24
    }
    public static void main(String args[]){
        startTask();

    }

}
15
BOSS
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 2);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);

// every night at 2am you run your task
Timer timer = new Timer();
timer.schedule(new YourTask(), today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); // period: 1 day
55
Daniel Gerber

Timer.schedule(TimerTask task, Date firstTime, long period)メソッドを使用して、今日firstTimeを午後2時に設定し、periodを24時間に設定できます。

指定された時刻から、固定遅延の繰り返し実行のために指定されたタスクをスケジュールします。後続の実行は、指定された期間で区切られたほぼ一定の間隔で行われます。

23
hmjd

これを行う最も簡単な方法は、常にWindowsのタスクスケジューラとLinuxのcronを使用することです。

ただし、Javaの場合は、 Quartz Scheduler をご覧ください

彼らのウェブサイトから:

Quartzは、すべてのJava EEまたはJava SEアプリケーション-から統合または実質的に一緒に使用できる、フル機能のオープンソースジョブスケジューリングサービスです。最小のスタンドアロンアプリケーションから最大のeコマースシステムQuartzを使用して、数万、数百、数万のジョブを実行するための単純または複雑なスケジュールを作成できます。タスクが標準として定義されているジョブJavaあなたがプログラムするためにあなたがプログラムするかもしれない事実上すべてを実行するかもしれないコンポーネント。

4
Ali

ScheduleAtFixedRateを使用してみてください(これによりタスクが繰り返されます)。何を実行するか(run()で)といつ実行するか(scheduledExecutionTime)を指定するTimerTaskオブジェクトを作成する必要があります。 scheduleAtFixedRateでは、最初の実行日を指定することもできます。

3
MilkDoctrine

Springの@Scheduled(cron = "0 0 14 * * *")..をsec、min、hours、day、month、dayOfWeekに使用してみませんか。 Vクール。 9:00〜11:00に9〜11、または最後のパラメーターにMON-FRIを指定することもできます。実行時に時間を設定したい場合、ほとんどのSpringの場合のように、これもプログラムで呼び出すことができます。これを参照してください: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html

サンプルを追加する

   @Scheduled(cron="0 0 14 * * *")
    public void customScheduler(){
        try{
            // do what ever you want to run repeatedly
        }catch(Exception e){
            e.printStackTrace();

        }
    }

また、これを含むクラスに@Componentアノテーションを付けて、Application.Java(クラスにmainメソッドが含まれる)クラスで@EnableSchedulingを提供して、アプリケーションでtaskschedulerを使用していることをSpringに認識させてください。

2
Apurva Singh

public void schedule(TimerTask task、Date firstTime、long period)を使用します

翌日に再びタスクを繰り返すには、期間を86400000ミリ秒(1日を意味します)に設定します

Date date2pm = new Java.util.Date();
date2pm.setHour(14);
date2pm.setMinutes(0);

Timer timer = new Timer();

timer.sc(myOwnTimerTask,date2pm, 86400000);
1
Rudy

期限 Java.util.Timer

Java 5.0はJava.util.concurrentパッケージを導入し、その中の同時実行ユーティリティの1つは、指定されたレートまたは遅延でタスクを繰り返し実行するためのスレッドプールであるScheduledThreadPoolExecutorです。複数のサービススレッドを許可し、さまざまな時間単位を受け入れ、TimerTaskのサブクラス化を必要としないため(Runnableを実装するだけ)、Timer/TimerTaskの組み合わせをより効果的に置き換えます。 1つのスレッドでScheduledThreadPoolExecutorを構成すると、Timerと同等になります。

そのため(このコードをクラスに追加します):

private ScheduledExecutorService scheduledExecutorService;

    public ScheduledSendLog() {
        init();
    }

    public void destroy() {
        this.scheduledExecutorService.shutdown();
    }

    private void init() {
        scheduledExecutorService =
                Executors.newScheduledThreadPool(1);
        System.out.println("---ScheduledSendLog created " + LocalDateTime.now());
        startSchedule(LocalTime.of(02, 00));
    }


    private void startSchedule(LocalTime atTime) {
        this.scheduledExecutorService.scheduleWithFixedDelay(() -> {
                    System.out.println(Thread.currentThread().getName() +
                            " |  scheduleWithFixedDelay | " + LocalDateTime.now());
                    // or whatever you want
                }, calculateInitialDelayInSec(atTime),
                LocalTime.MAX.toSecondOfDay(),
                TimeUnit.SECONDS);
    }

    private long calculateInitialDelayInSec(LocalTime atTime) {
        int currSec = LocalTime.now().toSecondOfDay();
        int atSec = atTime.toSecondOfDay();
        return (currSec < atSec) ?
                atSec - currSec : (LocalTime.MAX.toSecondOfDay() + atSec - currSec);

    }  
1
Alexey Simonov

この質問と次の2つの質問に対するほとんどの回答は、1日あたりのミリ秒が常に同じであると仮定しています
Javaで定期的なタスクをスケジュールする方法
ScheduledExecutorServiceを使用して特定の時間に特定のタスクを毎日実行する方法

ただし、夏時間とうるう秒のためにうまくいきません。これは、サービスが長年にわたって稼働しており、タイマーの精度が重要である場合、固定期間タイマーは選択できないことを意味します。

そこで、Java.util.Timerよりも柔軟なタイマーのためにコードスニペットを紹介したいと思います。

package szx;

import Java.time.LocalDateTime;
import Java.time.ZoneId;
import Java.util.Date;
import Java.util.Timer;
import Java.util.TimerTask;
import Java.util.function.Function;

public class ScheduledExecutor {
    public void scheduleRegularly(Runnable task, LocalDateTime firstTime,
            Function<LocalDateTime, LocalDateTime> nextTime) {
        pendingTask = task;
        scheduleRegularly(firstTime, nextTime);
    }

    protected void scheduleRegularly(LocalDateTime firstTime,
            Function<LocalDateTime, LocalDateTime> nextTime) {
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                scheduleRegularly(nextTime.apply(firstTime), nextTime);
                pendingTask.run();
            }
        }, Date.from(firstTime.atZone(ZoneId.systemDefault()).toInstant()));
    }

    private volatile Runnable pendingTask = null;
}

次に、上記のメソッドを次の方法で呼び出して、毎日午後2時にジョブを実行できます。

new ScheduledExecutor().scheduleRegularly(() -> {

    // do your task...

}, LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).withHour(14), thisTime -> thisTime.plusDays(1));

コードの背後にある基本的な考え方は、次のティックまでの残り時間を再計算し、毎回新しいタイマーを開始することです。

1
Mr. Ree