Search code examples
javamultithreadingjava-6

What is the behavior of running threads started by java.util.Timer when Timer.cancel() is called?


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

The reason for this question is that I have a timer running at one-minute intervals which makes a network request that sometimes takes up to 5 seconds to resolve, and then writes to a file on disk.

When the application is terminated, I need to clean up the file handlers, but I don't want to do that if the timer-initiated thread is in currently blocked on a network call, and may attempt to write to a closed file handler later.

It's hard to test deterministically what happens when Timer.stop() is called at an arbitrary point in time, so I'm hoping that someone who either works on Java or has solved a similar problem might be able to help.


Solution

  • From your update, it appears you mean Timer.cancel which explains what it does.

    /**
     * Terminates this timer, discarding any currently scheduled tasks.
     * Does not interfere with a currently executing task (if it exists).
     * Once a timer has been terminated, its execution thread terminates
     * gracefully, and no more tasks may be scheduled on it.
     *
     * <p>Note that calling this method from within the run method of a
     * timer task that was invoked by this timer absolutely guarantees that
     * the ongoing task execution is the last task execution that will ever
     * be performed by this timer.
     *
     * <p>This method may be called repeatedly; the second and subsequent
     * calls have no effect.
     */
    public void cancel() {
        synchronized(queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();  // In case queue was already empty.
        }
    }
    

    I assume you mean javax.swing.Timer as java.util.Timer doesn't have a stop() method, and javax.management.timer.Timer and sun.misc.Timer (have stop() methods but are rather obscure)

    AFAIK, Its a very bad idea to use this timer for IO as it uses the GUI thread and can cause it to lock up for periods of time.

    Looking at the code

    /**
     * Stops the <code>Timer</code>,
     * causing it to stop sending action events
     * to its listeners.
     *
     * @see #start
     */
    public void stop() {
        getLock().lock();
        try {
            cancelEvent();
            timerQueue().removeTimer(this);
        } finally {
            getLock().unlock();
        }
    }
    

    You can see it stop sending new tasks, but does interrupt or stop() running ones.