每小时运行一次Java代码

时间:2012-10-12 20:27:22

标签: java multithreading java-ee scheduled-tasks

我正在尝试编写一个简单的Java程序,当分针为20时,它每小时运行一些代码。问题是我正在做的事情是非常耗费CPU。我熟悉Quartz,但我正在寻找一个更简单的解决方案,任何想法?

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

13 个答案:

答案 0 :(得分:4)

一个简单的解决方案是使用Executors框架:

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

并使用一些逻辑来找出secondsToFirstOccurence。这可能涉及Calendar实例,但使用JodaTime会更方便。

答案 1 :(得分:2)

请注意,如果您的应用程序在托管环境(Web或ejb容器)内运行,则不允许使用Thread.sleep()或任何其他与线程相关的操作,请查看EJB restrictions页面。我对此提出警告,因为问题标记为java-ee,因此“简单应用程序”可能并非如此简单 - 如果它在Java EE容器内运行,则需要考虑其他注意事项。

如果您正在构建企业级应用程序,请忘记Thread.sleep()。寻找一个成熟的作业调度程序,使用Quartz,它是一个开源的,非常成熟和可靠的产品。或者使用Obsidian Scheduler,这是一个功能丰富的商业调度程序,具有比Quartz更多的开箱即用功能。

完全成熟的调度程序(但适合在容器内运行)的轻量级替代方法是使用Timer service

答案 2 :(得分:1)

您可能在来电之间寻找Thread.sleep()

答案 3 :(得分:1)

查看java.util.Timer方法scheduleAtFixedRate()。

答案 4 :(得分:1)

我建议您从java程序中删除调度逻辑。
通过这样做,您只能关注您希望程序执行的操作,并将调度部分留给操作系统。
另外,比如说你在某个时候决定编写一个c ++程序来执行你的java代码所知道的,你不必在你的新程序中实现cron逻辑

话虽如此:

  • 对于Linux,您有crontab
  • 对于Windows,您有windows task schedule
  • 对于Mac,我不确定,但鉴于它是基于UNIX的cron应该存在。

答案 5 :(得分:0)

将代码置于无限时间并使用

Thread.sleep(3600000);

之后的20点开始执行

示例

while(1==1) {
    //Your code here
    try{
         Thread.sleep(3600000);
    }
    catch (Exception e) {}
}

答案 6 :(得分:0)

为每小时执行的方法安排一个cron作业,而不是阻止sleep()调用,使用一些调度框架,如quartz

答案 7 :(得分: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();
}

}

答案 8 :(得分: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);
}
}

答案 9 :(得分: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);

然后重新安排

答案 10 :(得分:0)

所以绝对是ScheduledExecutorService很棒,因为很多其他答案都说明了。

如果您在Java EE 6服务器中,可以通过@ScheduleScheduleExpression获得一些乐趣

请参阅Have an EJB schedule tasks with "crontab syntax"

答案 11 :(得分: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();
        }
    }

答案 12 :(得分: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());
    }   
}