Elaborate Java.util.Timer

Source: Internet
Author: User
Tags terminates

The timer is used to manage deferred or recurring tasks that are performed in the background, where the tasks are expressed using Java.util.TimerTask. There are two ways to perform a task:

    • Execution at a fixed rate: two overloaded methods for Scheduleatfixedrate
    • Execution by fixed delay: 4 overloaded methods of schedule

Specific differences will be explained in detail later.

To implement a timed task, we only need to implement the TimerTask run method. Each task has the next execution time Nextexecutiontime (milliseconds), and if it is a recurring task, each execution will be updated to the next execution time, and will be executed when the nextexecutiontime is less than the current time.

first, the mode of use

The specific use of the timer is very simple, such as:

        Timer timer = new timer ();        Timer.schedule (New TimerTask () {            @Override public            void Run () {                System.out.println ("Timer is Running");            }        }, 2000);
The above timed task indicates that execution starts in 2 seconds and executes only once. Of course, you can also perform periodic tasks, just add the third parameter of schedule period, such as:

        Timer timer = new timer ();        Timer. Scheduleatfixedrate (New TimerTask () {            @Override public            void Run () {                System.out.println ("Timer is Running ");            }        }, 2000, 5000);
Indicates that execution starts after 2 seconds, and then executes every 5 seconds.

Second, the concrete realization of the analysis

For each timer, the background uses only one thread to perform all tasks. And all the tasks are saved to a task queue java.util.TaskQueue, which is an internal class of the timer, which is a priority queue, and the algorithm used is the least-binary heap (binary min heap).

The timer's documentation says:

After the last live reference to a Timer object goes away and all outstanding tasks has completed execution, the timer ' s Task execution thread terminates gracefully (and becomes subject to garbage collection).

This means (not exactly translated in the original text): When all the tasks in the task queue have been executed, that is, there is no one-time execution of the task, there is no periodic task, then the timer's background thread will gracefully terminate and become the object of garbage collection.

However, when testing, it was found that, after a one-off task, the task thread did not terminate, but always blocked, this does not know why, the use of the JDK is 1.7.0_79.

Use Jstack to see the status of this thread as follows:

"Timer-0" prio=5 tid=0x00007ff184046000 nid=0x5807 in object.wait () [0x000000011ebea000]   java.lang.Thread.State: Waiting (on object monitor) in Java.lang.Object.wait (Native Method)-Waiting on <0x00000007ab1bbea0> (a Java.util.TaskQueue) at java.lang.Object.wait (object.java:503) at Java.util.TimerThread.mainLoop (timer.java:526)- Locked <0x00000007ab1bbea0> (a java.util.TaskQueue) at Java.util.TimerThread.run (timer.java:505)

You can see that the timer task thread handles the blocking state.

There are four states of a timertask:

    • VIRGIN: The status of the newly created task, indicating that no execution has been scheduled
    • Scheduled: Scheduled execution, for non-cyclical tasks, indicates that the state is not executed when the task is added to the task execution queue, that is, when the timer.schedule is called
    • EXECUTED: Indicates that a non-recurring task has been executed or is in progress and has not been canceled
    • CANCELLED: Indicates that the task has been canceled when the Cancel method is called, and the task of that State is moved out of the queue each time it executes

Here's a look at what happens when Timer.schedule is called, and all calls to Timer.schedule are a private method called Sched.

such as deferred tasks (non-recurring tasks):

    public void Schedule (timertask task, long delay) {//delay cannot be less than 0 if (Delay < 0) throw new Ill        Egalargumentexception ("negative delay.");    Call the private Sched method, note that the execution time here is absolute time, and that period is 0 is not a recurring task Sched (Task, System.currenttimemillis () +delay, 0); private void Sched (TimerTask task, long time, long period) {if (Time < 0) throw new Illegalargu        Mentexception ("Illegal execution time."); Constrain value of period sufficiently to prevent numeric//overflow while still being effectively infinitely L        Arge.        if (Math.Abs (period) > (Long.max_value >> 1)) period >>= 1;                Synchronized (queue) {//If the timer has been canceled, then no more tasks can be performed, so throw an exception if (!thread.newtasksmaybescheduled)            throw new IllegalStateException ("Timer already cancelled."); Synchronized (Task.lock) {//If the task state you want to perform is not VIRGIN, throw an exception if (task.state! = timertask.virgin)                   throw new IllegalStateException ("Task already scheduled or cancelled");                Set the execution time of the task, note that the time is absolute task.nextexecutiontime = time;                Set the period for task execution task.period = period;            Set the status of the task to scheduled task.state = timertask.scheduled;            }//Add the task to the task queue, and other tasks perform thread debug execution Queue.add (Task);        Check that the next task that will be performed is not the currently added task, and if yes, notify the background task thread if (queue.getmin () = = Task) queue.notify (); }    }
The background thread that executes the task, the timer uses an inner class timerthread, which has a newtasksmaybescheduled property that indicates whether the task can still be performed, by default, true, and when the Cancel method is called, set to False. You will no longer be able to add or execute tasks. It also holds a reference to a task queue, rather than referencing the timer's task queue directly, because the timer cannot be garbage collected and the task thread does not terminate properly in order to prevent circular references.

Let's take a look at the implementation of this task thread:

    public void Run () {        try {            mainloop ()        }-finally {            //Someone killed this Thread, behave as if Timer cancel LED            synchronized (queue) {                newtasksmaybescheduled = false;                Queue.clear ();  Eliminate obsolete References            }}}    

is actually called the Mainloop method:

    private void Mainloop () {while (true) {try {TimerTask task;                Boolean taskfired; Synchronized (queue) {//wait for the task queue to become non-empty, if the task queue is empty and the timer is not canceled, block the thread, wait for the task queue to be non-empty, as you can see from the front, each time a task is added, the thread is notified to check the execution phase                    The tasks that should be while (Queue.isempty () && newtasksmaybescheduled) queue.wait (); if (Queue.isempty ()) break; Queue is empty and would forever remain; Die//Queue nonempty;                    Look at first evt and does the right thing long currenttime, executiontime;                    Gets the tasks in the current task queue and the next task that will be performed task = Queue.getmin (); Synchronized (Task.lock) {//If the task is canceled, remove the task from the queue and continue to the next task if (task.state =                            = timertask.cancelled) {queue.removemin ();  Continue No action required, pollQueue again} currenttime = System.currenttimemillis ();                        ExecutionTime = Task.nextexecutiontime; If the execution time of the current task is <= the current time, the task is performed, otherwise it is not executed, and it can be noted that if the execution time is a past time when the task is added, the IF (taskfired = (executio                            Ntime<=currenttime) {//If it is not a non-recurring task, remove the task from the task queue and set the status of the task to executed                                if (Task.period = = 0) {//non-repeating, remove queue.removemin ();                            Task.state = timertask.executed;                                } else {//repeating task, reschedule//If it is a recurring task, reset the next execution time of the task, it is important to note that period is likely to be positive and negative Queue.reschedulemin (task.period<0? currenttime-task.pe                            Riod:executiontime + task.period);                    }    }}//If there is no task to execute, wait until the next task execution time if (!taskfired)//task has N ' t yet fired;                Wait queue.wait (executiontime-currenttime); }//How to have a task to execute, here is the logical if (taskfired)//task fired to actually perform the task;            Run it, holding no locks task.run (); } catch (Interruptedexception e) {}}}
The logic where the next execution time of the task is reset:

Queue.reschedulemin (task.period<0 currenttime-task.period:executiontime + task.period);

Here the task execution cycle can be positive and negative:

    • Positive number: Indicates that execution at a fixed rate, such as the execution period is executed every 5 seconds, such as the last execution time is 20:51:30, then the next execution time is 20:51:35, if because the time to perform other tasks more than 5 seconds, such as 15 seconds, This may cause the task to not execute at a specified time, which destroys the rate at which the task executes, but executes 3 successive times.
    • Negative: Indicates that execution is scheduled according to a fixed delay, such as the execution period is executed every 5 seconds, under normal circumstances, such as it's execution time is 20:51:30, but because it takes 8 seconds to perform other tasks, that is, 20:51:38 when executing to the current task, the next execution time will be deferred backwards , that is, 20:51:43.

third, the shortcomings of the timer

1. Because there is only one thread executing a task, if a task takes too long to execute, it will break the timing accuracy of the other tasks. If a task executes every 1 seconds and another task takes 5 seconds to execute, then if it is a fixed-rate task, it will be executed 5 times in 5 seconds after the task is completed, and the fixed-delay task will lose 4 executions.

2. If an exception is thrown during the execution of a task, the execution thread terminates, causing the other tasks in the timer to no longer execute.

3, the timer uses absolute time, that is, a certain point in time, so it executes dependent on the system time, if the system time is modified, will cause the task may not be executed.

iv. better Alternative approaches

Because the timer has these flaws, In JDK1.5, we can use Scheduledthreadpoolexecutor to replace it, use the Executors.newscheduledthreadpool factory method, or use the Scheduledthreadpoolexecutor constructor to Create a timed task, which is based on the implementation of the thread pool, there is no such problem as the timer exists, when the number of threads is 1 o'clock, it is equivalent to a timer.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Elaborate Java.util.Timer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.