0

I'm trying to run a method once a week. For example, every Monday 8pm. I use this code:

    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;
    }
}

However, if I am right, the dosomething code is run continuously - as long as the calendar time has already passed. For example, now it has already been Monday, so the dosomething code is run all the time. A variabele gets increased, but it must be reset to 0 on Monday. The variable is now constantly 0, because it is reset again and again. If I use calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);, the variable is not reset, because it has not been Sunday yet. But as soon as it is Sunday 8pm, he will probably continue to reset the rest of that day.

I want the dosomething code to be executed only once at the one time specified. Can someone tell me how to adjust the code to achieve this?

Sorry for my English

lakeviking
  • 322
  • 1
  • 6
  • 18
  • I can't really tell if it works or not, but I think it should. Anyway, it might be worth looking at (ScheduledThreadPoolExecutor)[https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html] class - quoting Javadocs "It is effectively a more versatile replacement for the Timer/TimerTask combination". – Amongalen Jan 23 '20 at 09:28
  • 1
    Is this for a server, maybe it is better to use OS functionality for scheduling the job like cron on linux/unix or Scheduler on Windows – Joakim Danielson Jan 23 '20 at 09:30
  • It is for an Android application, in Android Studio. Does that make a difference? – lakeviking Jan 23 '20 at 09:35
  • Do you want this action ```PrintTask``` to be repeated every Monday? Or just the next Monday and never after that? If it is to be repeated, aren't you using the wrong ```schedule()```. I mean, shouldn't you be using the one that takes ```long period```? – Sree Kumar Jan 23 '20 at 09:49

2 Answers2

0

Please look at this question here(How i can run my TimerTask everyday 2 PM). It almost deals with same kind of problem.

Cancel the timer using the cancel api of Timer class, and reschedule the timer inside the run() method; this should prevent from updating the variable everytime.

0

The Timer class can be used to schedule things to run once, or multiple times. The way you are scheduling it at this moment will only make it once at the given time.

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

There are better options if you want to schedule tasks, for example the ScheduledExecutorService:

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

According to Java Concurrency in Practice:

  1. Timer can be sensitive to changes in the system clock, ScheduledThreadPoolExecutor isn't.
  2. Timer has only one execution thread, so long-running task can delay other tasks. ScheduledThreadPoolExecutor can be configured with any number of threads. Furthermore, you have full control over created threads, if you want (by providing ThreadFactory).
  3. Runtime exceptions thrown in TimerTask kill that one thread, thus making Timer dead :-( ... i.e. scheduled tasks will not run anymore. ScheduledThreadExecutor not only catches runtime exceptions, but it lets you handle them if you want (by overriding afterExecute method from ThreadPoolExecutor). Task which threw exception will be canceled, but other tasks will continue to run.

http://jcip.net/