Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constantly nulling out and re-creating Timer, TimerTask in Java

I know using Timer and TimerTask is no longer the current accepted practice (some have suggested using threads, others suggest using ScheduledExecutorService or its variants), so this question is not so much about good programming practice, but about the possibility of actual errors or exception.

Essentially, what I have is a servlet that keeps a running counter (which is a static Calendar object) that gets incremented every second. When a specified deadline is met (when we reach 10 minutes by default), I make a call from my application to a NIST time server to get the current time, which I then use to re-set my counter.

The same TimerTask-defined method that increments the counter (every second) is also the one that must be paused and re-scheduled every time I make a call to a NIST server (every ten minutes). I have been unsuccessful in pausing/cancelling the existing Timer/TimerTask objects before the NIST server call and re-scheduling the TimerTask after the call.

The exceptions that occur from this are described here: How do I use a timer in Java when required to set and cancel multiple times?

Suffice it to say, neither TimerTask nor Timer can be scheduled more than once, even by using purge() or cancel(), which appear to be only good for setting those objects as eligible for Java garbage collection.

Using wait() and notify() resulted in synchronization exceptions that I, unfortunately, did not have the time to figure out, so my initial experiment with threading was a failure.

What I ended up doing is this:

secondTickerTask.cancel();
secondTicker.purge();
secondTicker.cancel();

secondTickerTask = null;
secondTicker = null;

Date newCurrentTime = getNistTimeFromFirstWorkingServer();

// Save new date to current time, reset second counter.
setCurrentTimeAndDeadline(newCurrentTime);
startSecondIncrementTimer(newCurrentTime);

secondTicker = new Timer();
secondTickerTask = new TimerTask(){
    public void run(){
        incrementCurrentTimeAndTestDeadline();
    }

I ran this code over-night a few times, at 10-minute and 1-minute intervals between NIST server calls, and it worked smoothly.

So, after that long lead-up (thank you for your patience), this is what my question is: Being forced, for the moment, to use the code that I have, is there any damage that could result in the long run? If I keep making new TimerTask and Timer objects while nulling out the old ones over, let's say, a period of a month, or six months, will I force the Server to run out of memory? Is Java's garbage collection robust enough to handle this sort of use? Can any other scary thing happen?

Thank you very much for your time, - Eli

like image 590
justian17 Avatar asked Nov 02 '22 11:11

justian17


1 Answers

Java will handle the creation and abandonment of the timer tasks just fine. You need to ensure that you drop all references to the timers when you are done with them, which it appears you are doing, and then when the GC runs it will clean up any garbage the Timers introduced.

You are safe.

You should note that, over long periods of time, some Java processes tend to keep allocating memory until they hit their -Xmx limit. This does not mean that there is a problem (because that space will be reused by the GC), but it also means that, if you want a long-running Java process to have a relatively small footprint that you should not specify an -Xmx much larger than what you actually need.

like image 143
rolfl Avatar answered Nov 15 '22 06:11

rolfl