Java:如何在指定的时间仅运行一次此代码?

问题描述 投票:0回答:1

我正在尝试每周运行一次方法。例如,每个星期一晚上8点。我使用此代码:

    Timer timer = new Timer();

    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    calendar.set(Calendar.HOUR_OF_DAY, 20);
    calendar.set(Calendar.MINUTE, 00);
    calendar.set(Calendar.SECOND, 00);
    Date time = calendar.getTime();

    timer.schedule(new PrintTask(),
            time);

    // other code where variable gets increased



public class PrintTask extends TimerTask {
    public void run() {

          variable = 0;
    }
}

但是,如果我是对的,只要日历时间已经过去,dosomething代码就会连续运行。例如,现在已经是星期一,因此dosomething代码始终运行。 variabele增加,但必须在星期一将其重置为0。该变量现在始终为0,因为它会一次又一次地重置。如果使用calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);,则该变量不会重置,因为尚未到周日。但是,一旦到了周日晚上8点,他可能会继续重置当天的其余时间。

我希望dosomething代码在指定的一次仅执行一次。有人可以告诉我如何调整代码以实现此目标吗?

对不起,我的英语

java timer calendar scheduler
1个回答
0
投票

[请在此处查看此问题(How i can run my TimerTask everyday 2 PM)。它几乎处理相同的问题。

使用Timer类的cancel api取消计时器,并在run()方法中重新安排计时器;这应该防止每次都更新变量。


0
投票

Timer类可用于安排事物运行一次或多次。此时的调度方式只会在给定的时间进行一次。

https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html#schedule(java.util.TimerTask,%20java.util.Date)

如果要安排任务,则有更好的选择,例如ScheduledExecutorService:

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

根据实践中的Java并发性:

  1. 计时器可能对系统时钟的变化敏感,ScheduledThreadPoolExecutor则不敏感。
  2. 计时器只有一个执行线程,因此长时间运行的任务可能会延迟其他任务。 ScheduledThreadPoolExecutor可以配置为任何数量的线程。此外,您可以完全控制创建线程(如果需要)(通过提供ThreadFactory)。
  3. 在TimerTask中抛出的运行时异常会杀死该线程,从而使Timer失效:-( ...,即,计划任务将不再运行。ScheduledThreadExecutor不仅捕获运行时异常,而且还捕获使您可以根据需要处理它们(通过重写afterExecute方法来自ThreadPoolExecutor)。抛出异常的任务将被取消,但其他任务将继续运行。

http://jcip.net/

© www.soinside.com 2019 - 2024. All rights reserved.