Java Monthly Timer

I am trying to create a Timer / TimerTask that will work on the same day of every month. I cannot schedule a repeating timer, because a month will not always be the same length of time.

So here is my solution:

public class MyTask extends TimerTask {
    public void run(){
        //do process file stuff

        if(scheduledExecutionTime() != 0){
            TimerHelper.restartMyTimer();
        }
    }
}

public class TimerHelper {
    public static HashTable timersTable = new HashTable();

    public static void restartMyTimer(){
        Calendar runDate = Calendar.getInstance();
        runDate.set(Calendar.DAY_OF_MONTH, 1);
        runDate.set(Calendar.HOUR_OF_DAY, 4);
        runDate.set(Calendar.MINUTE, 0);
        runDate.add(Calendar.MONTH, 1);//set to next month

        MyTask myTask = new MyTask();
        Timer myTimer = new Timer();

        myTimer.schedule(myTask, runDate.getTime());

        timersTable = new HashTable();//keeping a reference to the timer so we 
        timersTable.put("1", myTimer);//have the option to cancel it later
    }
}

The problem, I think I am faced with the fact that since the first TimerTask creates a second timer, will the first timer be saved because it created the second? After the code ends the first timer, will this thread and object take care of garbage collection? Over time, I do not want to create a bunch of threads that do nothing but are not deleted. Perhaps I do not have a proper understanding of how streams and timers work ...

I am open to suggestions on other ways to create a monthly timer if I do not need to use third-party JARs.

Thank!

+3
7

, , , , , / "" , gc'ed.

12 , , , . .

. : , .

package monthly.schedule;

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

public class MonthlyTimer { 
    // What to do
    private final Runnable whatToDo;

    // when 
    private final int dayOfMonth;
    private final int hourOfDay;

    // The current timer
    private Timer current = new Timer();//to avoid NPE

    public void cancelCurrent() { 
        current.cancel();// cancel this execution;
        current.purge(); // removes the timertask so it can be gc'ed
    }

    // create a new instance
    public static MonthlyTimer schedule( Runnable runnable, int dayOfMonth, int hourOfDay ) { 
        return new MonthlyTimer( runnable, dayOfMonth, hourOfDay );
    }

    private MonthlyTimer(Runnable runnable, int day, int hour ) { 
        this.whatToDo = runnable;
        this.dayOfMonth = day;
        this.hourOfDay = hour;
        schedule();
    }
    // Schedules the task for execution on next month. 
    private void schedule() { 
        // Do you mean like this?
        cancelCurrent();
        current = new Timer(); // assigning a new instance
        // will allow the previous Timer to be gc'ed

        current.schedule( new TimerTask() { 
            public void run() { 
                try { 
                    whatToDo.run();
                } finally { 
                    schedule();// schedule for the next month
                }
            }
        } , nextDate() );           
    }
    // Do the next date stuff
    private Date nextDate() { 
        Calendar runDate = Calendar.getInstance();
        runDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        runDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
        runDate.set(Calendar.MINUTE, 0);
        runDate.add(Calendar.MONTH, 1);//set to next month
        return runDate.getTime();
    }
}

class UseIt { 
    public static void main( String [] args ) { 
        int the1st = 1;
        int at16hrs = 16;

        MonthlyTimer t = MonthlyTimer.schedule( new Runnable() { 
            public void run() { 
                System.out.println( "Hola" );
            }}, the1st, at16hrs );

        // will print "Hola" every 1st at 16:00 hrs.
       // if needed you can cancel with: 
        t.cancelCurrent();

    }
}
+2

Quartz CronTrigger, , , Quartz .

, CronTrigger.

Quartz - , .

+5

, , :

 ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor();

 es.schedule(new MyTask(), numberOfDaysRemaining(), TimeUnit.DAYS);


class MyTask implements Runnable {
 public void run() {
  try {
   // do it
  } finally {
   es.schedule(new MyTask(), numberOfDaysRemaining(), TimeUnit.DAYS);
  }
 }
}

JodaTime, .

+4

cron ...

+1
0

, DelayQueue. , ScheduledExecutorService.

0

? - . , .

:

MonthlyTimer extends Timer {
     public void execute(TimerTask task, Date date, int dayOfMonth) {
          this.schedule(new TimerTaskWithCallback(task, dayOfMonth, this), date);
     }

     void taskCallback(TimerTaskWithCallback task) {
          this.schedule(new TimerTaskWithCallback(task.getImpl()), nextDate(task.getDayOfMonth())); //next date could be used from Oscar post.
     }
}

TimerTaskWithCallback simply executes MonthlyTimer.taskCallback after completing the original task. Could have "try {} catch {} finally {}" glue code.

0
source

Source: https://habr.com/ru/post/1773254/


All Articles