3

分針が 20 のときに 1 時間ごとにコードを実行する単純な Java プログラムを作成しようとしています。私は Quartz に精通していますが、もっとシンプルなソリューションを探しています。何かアイデアはありますか?

    boolean run = true;
    while(run){
        Calendar calendar = new GregorianCalendar();
        int minute = calendar.get(Calendar.MINUTE);
        if(minute == 20){
            //Do some Stuff             
        }
    }
4

13 に答える 13

5

簡単な解決策は、Executors フレームワークを使用することです。

final ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
s.scheduleAtFixedRate(task, secondsToFirstOccurence, 60*60, TimeUnit.SECONDS);

そして、いくつかのロジックを使用して見つけますsecondsToFirstOccurence。これにはおそらくCalendarインスタンスが含まれますが、JodaTime を使用するとより便利になります。

于 2012-10-12T20:38:24.393 に答える
2

Thread.sleep()アプリケーションが管理された環境 (Web または ejb コンテナー) 内で実行されている場合、またはその他のスレッド関連の操作を使用することは許可されていないことに注意してください。その点については、 EJB 制限ページを参照してください。質問にタグが付けられているため、これについて警告しjava-eeます。したがって、「単純なアプリケーション」は結局のところそれほど単純ではない可能性があります.Java EEコンテナー内で実行されている場合、注意すべき追加の考慮事項があります.

エンタープライズ レベルのアプリケーションを構築している場合は、Thread.sleep(). 本格的なジョブ スケジューラである Use Quartzを使用してください。これは、オープン ソースであり、非常に成熟した信頼性の高い製品です。または、Quartz よりもすぐに使える機能を備えた機能豊富な商用スケジューラーであるObsidian Schedulerを使用します。

本格的なスケジューラの軽量な代替手段 (ただし、コンテナー内での実行に適しています) は、Timer サービスを使用することです。

于 2012-10-12T20:31:21.513 に答える
1

Java プログラムからスケジューリング ロジックを削除することをお勧めします。
これにより、プログラムに実行させたいことだけに集中し、スケジューリングの部分は OS に任せることができます。
また、たとえば、ある時点で、Java コードが知っていることを行う C++ プログラムを作成することを決定したとします。新しいプログラムに cron ロジックを実装する必要はありません

于 2012-10-17T10:57:03.347 に答える
1

Thread.sleep()あなたは呼び出しの間に探しているかもしれません

于 2012-10-12T20:28:59.083 に答える
1

java.util.Timerメソッドの scheduleAtFixedRate()を見てください。

于 2012-10-12T20:34:24.403 に答える
0

もう一つの例

import java.text.SimpleDateFormat;
import java.util.Date;

public class TestHour {

    private static final int MINUNTE = 20;

    public static void main(String args[]) {
        while (true) {
            SimpleDateFormat bartDateFormat = new SimpleDateFormat("mm");
            Date date = new Date();
            int currentMin = new Integer(bartDateFormat.format(date))
                    .intValue();
            if (currentMin < MINUNTE) {
                sleepMinutes(MINUNTE - currentMin);
            } else if (currentMin > MINUNTE) {
                sleepMinutes(60 - currentMin + MINUNTE);
            } else {
                // DO SOMETHING EVERY HOUR
                System.out.println("come on do it!!!");
                sleepMinutes(60);
            }
        }
    }

    private static void sleepMinutes(int minutes) {
        try {
            System.out.println("Sleeping for " + minutes);
            Thread.sleep(minutes * 1000*60);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
于 2012-10-12T20:58:07.610 に答える
0

このようなものを使用してください

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 20);
calendar.set(Calendar.MINUTE, 20);
calendar.set(Calendar.SECOND, 0);
Date time = calendar.getTime();
Timer timer = new Timer();
timer.schedule(new SomeTask(), time);

そして再スケジュール

于 2012-10-12T20:38:40.847 に答える
0

コードを無限の while に入れて使用する

Thread.sleep(3600000);

20時から実行開始

while(1==1) {
    //Your code here
    try{
         Thread.sleep(3600000);
    }
    catch (Exception e) {}
}
于 2012-10-12T20:29:19.110 に答える
0

呼び出しをブロックするのではなく、1 時間ごとに実行するメソッドの cron ジョブをスケジュールします。クォーツsleep()などのスケジューリング フレームワークを使用します。

于 2012-10-12T20:32:33.597 に答える
0

今日学んだことのさらに別の例。

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class SchedulerExample2 implements Runnable{

    public static void main(String args[]) {

        Calendar due = Calendar.getInstance();
        due.set(Calendar.MILLISECOND, 0);
        due.set(Calendar.SECOND, 0);
        due.set(Calendar.MINUTE, 20);
        if (due.before(Calendar.getInstance())) {
            due.add(Calendar.HOUR, 1);
        }
        long milliSecondsToNextOcurrence =  due.getTimeInMillis() - new Date().getTime();
        final ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
        ShedulerExample task = new  ShedulerExample();
        s.scheduleAtFixedRate(task, milliSecondsToNextOcurrence, 60*60*1000, TimeUnit.MILLISECONDS);
    }

    @Override
    public void run() {
            System.out.println("hola->"+new Date());
    }   
}
于 2012-10-12T21:28:07.003 に答える
0

1) 最初のエントリで、次の期日を計算します。

2) java.util.Timer.schedule( ) を使用する

3) 各実行のスケジュールを変更します。

コード

package tests;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class App201210130040 {


private static Timer timer = new Timer(false);

public static void schedule() {
    Calendar due = Calendar.getInstance();
    due.set(Calendar.MINUTE, 20);
    if( due.before(Calendar.getInstance()) ) {
        due.add(Calendar.HOUR, 1);
    }

    System.out.println("Scheduled to " + due.getTime().toString());

    timer.schedule(new TimerTask() {

        @Override
        public void run() {

            System.out.println("due");

            schedule();
        }

    }, due.getTime());

}


public static void main(String[] args) {
    schedule();
}

}
于 2012-10-12T20:35:52.247 に答える
0

ScheduledExecutorServiceをご覧ください。

class BeeperControl {
private final ScheduledExecutorService scheduler = 
   Executors.newScheduledThreadPool(1);

public void beepForAnHour() {
    final Runnable beeper = new Runnable() {
            public void run() { System.out.println("beep"); }
        };
    final ScheduledFuture<?> beeperHandle = 
        scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
    scheduler.schedule(new Runnable() {
            public void run() { beeperHandle.cancel(true); }
        }, 60 * 60, SECONDS);
}
}
于 2012-10-12T20:36:39.467 に答える
0

したがって、他の多くの回答が述べているように、 ScheduledExecutorServiceは間違いなく素晴らしいです。

Java EE 6 サーバーを使用している場合は@ScheduleScheduleExpression

「crontab 構文」を使用して EJB スケジュール タスクを設定するを参照してください。

于 2012-10-12T20:46:33.877 に答える