简体   繁体   中英

java timer scheduled tasks

What happens in the following case?

Timer t = new Timer();
t.schedule(...);
t = new Timer();

Specifically, what happens to the the tasks that I've scheduled on Timer t after I've assigned a new instance of Timer to t?

They doesn't go away. Each Timer object is associated with a background process. Even when you remove all references to your Timer in your program, the background process will still continue to run (it holds it's own reference to the object). Because of this, the object will not be subject to garbage collection.

See the official documentation for details.

Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially... After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur.

It will run without any problems. The only thing is that if you won't be able to cancel the first timer (if you actually want to cancel it)

The API docs for Timer lead me to believe that losing a reference to the timer will not affect it at all. It appears that any scheduled tasks will still definitely be executed. The timer instance cannot be garbaged collected and the app cannot shut down until the last task scheduled with that Timer has finished executing. Excerpt from the docs:

"After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur. By default, the task execution thread does not run as a daemon thread, so it is capable of keeping an application from terminating. If a caller wants to terminate a timer's task execution thread rapidly, the caller should invoke the timer's cancel method."

for example

private ScheduledExecutorService scheduler;
private AccurateScheduledRunnable periodic;
private ScheduledFuture<?> periodicMonitor;
private int taskPeriod = 30;
private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
private SimpleDateFormat sdfHour = new SimpleDateFormat("HH");

. . .

  scheduler = Executors.newSingleThreadScheduledExecutor();   
            periodic = new AccurateScheduledRunnable() {

                private final int ALLOWED_TARDINESS = 200;
                private int countRun = 0;
                private int countCalled = 0;

                @Override
                public void run() {
                    countCalled++;
                    if (this.getExecutionTime() < ALLOWED_TARDINESS) {
                        countRun++;
                        dateNext = new java.util.Date();
                        dateLast = new java.util.Date();
                        long tme = dateNext.getTime();
                        tme += (taskPeriod * 60) * 1000;
                        dateNext.setTime(tme);
                        //System.out.println("");
                        //System.out.println("");
                        //System.out.println("Next Sheduled Time at : " + sdf.format(dateNext));
                        //System.out.println("Periodic Cycle In : " + (countRun) + "/" + countCalled + " at " + sdf.format(dateLast));
                        //ti.displayMessage(null, " Running Sheduled Task at " + sdf.format(new Date()), TrayIcon.MessageType.NONE);
                        distAppInfo();
                    }
                }
            };
            periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.MINUTES);
            periodic.setThreadMonitor(periodicMonitor);

and implements Monitor that's returns fe remaining time to the next Shedule

long she = periodicMonitor.getDelay(TimeUnit.SECONDS);

and Monitor

abstract class AccurateScheduledRunnable implements Runnable {

    private ScheduledFuture<?> thisThreadsMonitor;

    public void setThreadMonitor(ScheduledFuture<?> monitor) {
        this.thisThreadsMonitor = monitor;
    }

    protected long getExecutionTime() {
        long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS);
        return delay;
    }
}

It would depend on which Timer.schedule(..) method that you plan to utilize. If the timer is set to repeatedly execute then assigning a new instance of Timer to t will not cause garbage collection as the timer thread will remain active.If you set the timer for one-time execution then the object will get garbage collected..at least that's what the documentation says..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM