【问题标题】:Run java function every hour每小时运行一次java函数
【发布时间】:2015-11-20 14:16:07
【问题描述】:

我想每小时运行一个函数,每小时通过电子邮件向用户发送他们进度的屏幕截图。我在一个名为 sendScreenshot() 的函数中进行了代码设置

如何在后台运行此计时器以每小时调用一次函数 sendScreenshot(),而程序的其余部分正在运行?

这是我的代码:

public int onLoop() throws Exception{
    if(getLocalPlayer().getHealth() == 0){
        playerHasDied();
    }
    return Calculations.random(200, 300);

}

public void sendScreenShot() throws Exception{
    Robot robot = new Robot();
    BufferedImage screenshot = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
    screenshotNumber = getNewestScreenshot();
    fileName = new File("C:/Users/%username%/Dreambot/Screenshots/Screenshot" + screenshotNumber +".");
    ImageIO.write(screenshot, "JPEG", fileName);

    mail.setSubject("Your hourly progress on account " + accName);
    mail.setBody("Here is your hourly progress report on account " + accName +". Progress is attached in this mail.");
    mail.addAttachment(fileName.toString());
    mail.setTo(reciepents);
    mail.send();

}

【问题讨论】:

标签: java schedule


【解决方案1】:

使用ScheduledExecutorService

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        sendScreenShot();
    }
}, 0, 1, TimeUnit.HOURS);

优先使用ScheduledExecutorService 而不是TimerJava Timer vs ExecutorService?

【讨论】:

  • 我怎样才能让它像作为后台服务运行一样,这样即使在计算机启动时应用程序也没有运行,但线程在其定义的时间自动运行?
  • @A.Aleem11 如果您想要免费和开源的东西,请使用 Quartz Scheduler 或我们的 Obsidian Scheduler。
  • 更短,使用 Java 8:Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> sendScreenShot(), 0, 1, TimeUnit.HOURS)
【解决方案2】:

根据this article by Oracle,也可以使用@Schedule注解:

@Schedule(hour = "*")
public void doSomething() {
    System.out.println("hello world");
}

例如,秒和分钟的值可以是 0-59、小时 0-23、月 1-12。

那里还描述了其他选项。

【讨论】:

  • 这是给 JEE 的,他很可能在使用 JSE
  • 我猜这是最优雅的方式。谢谢。
【解决方案3】:

java 的 Timer 在这里可以正常工作。

http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html

Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
    public void run() {
        // ...
    }
}, delay, 1 * 3600 * 1000); // 1 hour between calls

【讨论】:

  • 但这需要一些查看注释的上下文,例如企业服务器、spring 等。
  • @user1052080 此解决方案不需要任何注释。
【解决方案4】:

对于这种类型的周期执行,即每天或每小时,您只需要使用这样的计时器:

public static void main(String[] args) throws InterruptedException {
        Calendar today = Calendar.getInstance();
        today.set(Calendar.HOUR_OF_DAY, 7);
        today.set(Calendar.MINUTE, 45);
        today.set(Calendar.SECOND, 0);

        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("I am the timer");
            }
        };
//        timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); // period: 1 day
        timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(5, TimeUnit.SECONDS)); // period: 5 seconds

    }

此示例将从当前日期和上午 7:45 开始每 5 秒执行一次 timetask。 祝你好运。

【讨论】:

    【解决方案5】:
    while (true) {
            
            DateTime d = new DateTime();
            switch(d.getMinuteOfHour()) {
                
            case 56:
                runHourly();
                break;
                
            case 41:
                if(d.getHourOfDay() == 2) {
                    runAt0241Daily();
                }
                break;
            }   
            SUM.wait(59000);
        }
    

    这对于你可以控制和理解的东西怎么样?

    【讨论】:

      猜你喜欢
      • 2020-09-11
      • 1970-01-01
      • 2012-10-03
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多