当前位置 : 主页 > 网络编程 > 其它编程 >

Java中定时器相关实现的介绍与对比之:Timer和TimerTask

来源:互联网 收集:自由互联 发布时间:2023-07-02
Timer和TimerTaskJDK自带具体的定时任务由TimerTask指定定时任务的执行调度由Timer设定。Timer和TimerTask均在 Timer和TimerTask JDK自带具体的定时任务由TimerTask指定定时任务的执行调度由Timer设定。
Timer和TimerTaskJDK自带具体的定时任务由TimerTask指定定时任务的执行调度由Timer设定。Timer和TimerTask均在

Timer和TimerTask

JDK自带具体的定时任务由TimerTask指定定时任务的执行调度由Timer设定。Timer和TimerTask均在包java.util里实现。

本文基于java version "1.8.0_191"展开分析学习。

  • TimerTask负责实现指定的任务
  • 创建一个TimerTask实例。/** * Creates a new timer task. */ protected TimerTask() { }
  • 抽象方法实现具体的任务

    /*** The action to be performed by this timer task.*/public abstract void run();

  • cancel方法取消任务的调度而不是任务的执行。 对于one-time execution和repeated execution任务 如果任务尚未执行则对应的任务将永远不会执行 如果任务正在执行则等待当前任务执行之后再也不会被调度到。 run方法中调用该方法则任务不会再被调度。 该方法可以反复调用但只有第一次调用有效后续调用无效
  • /*** return true if this task is scheduled for one-time execution and has* not yet run, or this task is scheduled for repeated execution.* Returns false if the task was scheduled for one-time execution* and has already run, or if the task was never scheduled, or if* the task was already cancelled. (Loosely speaking, this method* returns true if it prevents one or more scheduled* executions from taking place.)*/public boolean cancel() {synchronized(lock) {boolean result (state SCHEDULED);state CANCELLED;return result;}}

  • scheduledExecutionTime方法返回此任务最近实际执行的已安排执行时间。 如果在任务执行过程中调用此方法则返回值为此任务执行的已安排执行时间。 通常从一个任务的 run 方法中调用此方法以确定当前任务执行是否能充分及时地保证完成已安排活动
  • /*** return the time at which the most recent execution of this task was* scheduled to occur, in the format returned by Date.getTime().* The return value is undefined if the task has yet to commence* its first execution.* see Date#getTime()*/public long scheduledExecutionTime() {synchronized(lock) {return (period <0 ? nextExecutionTime period: nextExecutionTime - period);}}

  • Timer负责任务的调度执行 Timer类共有14个方法其中4个构造方法9个与调度相关的方法。
  • 其调度是通过队列实现的相关成员变量为:

    /*** The timer task queue. This data structure is shared with the timer* thread. The timer produces tasks, via its various schedule calls,* and the timer thread consumes, executing timer tasks as appropriate,* and removing them from the queue when theyre obsolete.*/private final TaskQueue queue new TaskQueue();/*** The timer thread.*/private final TimerThread thread new TimerThread(queue);/*** This object causes the timers task execution thread to exit* gracefully when there are no live references to the Timer object and no* tasks in the timer queue. It is used in preference to a finalizer on* Timer as such a finalizer would be susceptible to a subclasss* finalizer forgetting to call it.*/private final Object threadReaper new Object() {protected void finalize() throws Throwable {synchronized(queue) {thread.newTasksMayBeScheduled false;queue.notify(); // In case queue is empty.}}};

  • 其核心调度实现是private void sched(TimerTask task, long time, long period)。 其调度接口与实现分析如下

    /*** Schedule the specified timer task for execution at the specified* time with the specified period, in milliseconds. If period is* positive, the task is scheduled for repeated execution; if period is* zero, the task is scheduled for one-time execution. Time is specified* in Date.getTime() format. This method checks timer state, task state,* and initial execution time, but not period.** throws IllegalArgumentException if time is negative.* throws IllegalStateException if task was already scheduled or* cancelled, timer was cancelled, or timer thread terminated.* throws NullPointerException if {code task} is null*/private void sched(TimerTask task, long time, long period) {if (time (Long.MAX_VALUE >> 1))period >> 1;synchronized(queue) {if (!thread.newTasksMayBeScheduled)throw new IllegalStateException("Timer already cancelled.");synchronized(task.lock) {if (task.state ! TimerTask.VIRGIN)throw new IllegalStateException("Task already scheduled or cancelled");task.nextExecutionTime time;task.period period;task.state TimerTask.SCHEDULED;}queue.add(task);if (queue.getMin() task)queue.notify();}}

  • 对外提供的接口
    • public void schedule(TimerTask task, Date time)

    Schedules the specified task for execution at the specified time. Ifthe time is in the past, the task is scheduled for immediate execution.param task task to be scheduled.param time time at which task is to be executed.

    • public void schedule(TimerTask task, Date firstTime, long period)

    Schedules the specified task for repeated fixed-delay execution,beginning at the specified time. Subsequent executions take place atapproximately regular intervals, separated by the specified period.In fixed-delay execution, each execution is scheduled relative tothe actual execution time of the previous execution. If an executionis delayed for any reason (such as garbage collection or otherbackground activity), subsequent executions will be delayed as well.In the long run, the frequency of execution will generally be slightlylower than the reciprocal of the specified period (assuming the systemclock underlying Object.wait(long) is accurate). As aconsequence of the above, if the scheduled first time is in the past,it is scheduled for immediate execution.Fixed-delay execution is appropriate for recurring activitiesthat require "smoothness." In other words, it is appropriate foractivities where it is more important to keep the frequency accuratein the short run than in the long run. This includes most animationtasks, such as blinking a cursor at regular intervals. It also includestasks wherein regular activity is performed in response to humaninput, such as automatically repeating a character as long as a keyis held down.param task: task to be scheduled.param firstTime: First time at which task is to be executed.param period: time in milliseconds between successive task executions.

    • public void schedule(TimerTask task, long delay)

    Schedules the specified task for execution after the specified delay.

    • public void schedule(TimerTask task, long delay, long period)

    Schedules the specified task for repeated fixed-delay execution,beginning after the specified delay. Subsequent executions take placeat approximately regular intervals separated by the specified period.In fixed-delay execution, each execution is scheduled relative tothe actual execution time of the previous execution. If an executionis delayed for any reason (such as garbage collection or otherbackground activity), subsequent executions will be delayed as well.In the long run, the frequency of execution will generally be slightlylower than the reciprocal of the specified period (assuming the systemclock underlying Object.wait(long) is accurate).Fixed-delay execution is appropriate for recurring activitiesthat require "smoothness." In other words, it is appropriate foractivities where it is more important to keep the frequency accuratein the short run than in the long run. This includes most animationtasks, such as blinking a cursor at regular intervals. It also includestasks wherein regular activity is performed in response to humaninput, such as automatically repeating a character as long as a keyis held down. 上述方法调用过程中如果任务执行过程出现异常原因导致延时比如某次任务处理时间过长 则后续任务将会依次延时。即以固定间隔执行任务调度

    • public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

    Schedules the specified task for repeated fixed-rate execution,beginning at the specified time. Subsequent executions take place atapproximately regular intervals, separated by the specified period.In fixed-rate execution, each execution is scheduled relative to thscheduled execution time of the initial execution. If an execution isdelayed for any reason (such as garbage collection or other backgroundactivity), two or more executions will occur in rapid succession to"catch up." In the long run, the frequency of execution will beexactly the reciprocal of the specified period (assuming the systemclock underlying Object.wait(long) is accurate). As aconsequence of the above, if the scheduled first time is in the past,then any "missed" executions will be scheduled for immediate "catch upexecution.Fixed-rate execution is appropriate for recurring activities thatare sensitive to absolute time, such as ringing a chime everyhour on the hour, or running scheduled maintenance every day at aparticular time. It is also appropriate for recurring activitieswhere the total time to perform a fixed number of executions isimportant, such as a countdown timer that ticks once every second forten seconds. Finally, fixed-rate execution is appropriate forscheduling multiple repeating timer tasks that must remain synchronizewith respect to one another.

    • public void scheduleAtFixedRate(TimerTask task, long delay, long period)

    Schedules the specified task for repeated fixed-rate execution,beginning after the specified delay. Subsequent executions take placeat approximately regular intervals, separated by the specified period.In fixed-rate execution, each execution is scheduled relative to thescheduled execution time of the initial execution. If an execution isdelayed for any reason (such as garbage collection or other backgroundactivity), two or more executions will occur in rapid succession to"catch up." In the long run, the frequency of execution will beexactly the reciprocal of the specified period (assuming the systemclock underlying Object.wait(long) is accurate).Fixed-rate execution is appropriate for recurring activities thatare sensitive to absolute time, such as ringing a chime everyhour on the hour, or running scheduled maintenance every day at aparticular time. It is also appropriate for recurring activitieswhere the total time to perform a fixed number of executions isimportant, such as a countdown timer that ticks once every second forten seconds. Finally, fixed-rate execution is appropriate forscheduling multiple repeating timer tasks that must remain synchronizedwith respect to one another.

    上述方法调用过程中如果出现某次任务执行时间过长则后续任务会加快执行频率 可能会出现连续多次调用"跟"上进度。即以近似固定频率执行任务调度。

  • Deamonsource code:

    import java.util.Timer;import java.util.TimerTask;import static java.lang.Thread.sleep;class TimerTaskDeamon extends TimerTask{private String jobName "";public TimerTaskDeamon(String jobName){super();this.jobName jobName;}Overridepublic void run() {System.out.println("--------------->");System.out.println("execute " "currentTimeMillis" ": " System.currentTimeMillis());System.out.println("execute " "scheduledExecutionTime" ": " scheduledExecutionTime());System.out.println("execute " jobName ": ");try {sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("execute " "currentTimeMillis" ": " System.currentTimeMillis());System.out.println("execute " "scheduledExecutionTime" ": " scheduledExecutionTime());System.out.println("<---------------");}}public class timerDeamon {static Timer timer new Timer();public static void main(String[] args){long delay 1 * 1000;long period 1000;timer.schedule(new TimerTaskDeamon("job1"), delay, period);timer.schedule(new TimerTaskDeamon("job2"),2*delay, 2*period);}}

    output:

    --------------->execute currentTimeMillis: 1544331346389execute scheduledExecutionTime: 1544331346389execute job1: execute currentTimeMillis: 1544331351401execute scheduledExecutionTime: 1544331346389<------------------------------>execute currentTimeMillis: 1544331351401execute scheduledExecutionTime: 1544331351401execute job2: execute currentTimeMillis: 1544331356403execute scheduledExecutionTime: 1544331351401<---------------

  • TaskQueue实现* This class represents a timer task queue: a priority queue of TimerTasks, * ordered on nextExecutionTime. Each Timer object has one of these, which it * shares with its TimerThread. Internally this class uses a heap, which * offers log(n) performance for the add, removeMin and rescheduleMin * operations, and constant time performance for the getMin operation. 关键成员变量private TimerTask[] queue new TimerTask[128]; 支持任务的添加、删除和重新调度等操作。Priority queue represented as a balanced binary heap: the two children of queue[n] are queue[2*n] and queue[2*n1]. The priority queue is ordered on the nextExecutionTime field: The TimerTask with the lowest nextExecutionTime is in queue[1] (assuming the queue is nonempty). For each node n in the heap, and each descendant of n, d, n.nextExecutionTime < d.nextExecutionTime.
  • TimerThread TimerThread继承自Thread类。

    This "helper class" implements the timers task execution thread, which waits for tasks on the timer queue, executions them when they fire, reschedules repeating tasks, and removes cancelled tasks and spent non-repeating tasks from the queue.

    核心调度方法如下

    public void run() {try {mainLoop();} finally {// Someone killed this Thread, behave as if Timer cancelledsynchronized(queue) {newTasksMayBeScheduled false;queue.clear(); // Eliminate obsolete references}}}private void mainLoop() {while (true) {try {TimerTask task;boolean taskFired;synchronized(queue) {// Wait for queue to become non-emptywhile (queue.isEmpty() if (queue.isEmpty())break; // Queue is empty and will forever remain; die// Queue nonempty; look at first evt and do the right thinglong currentTime, executionTime;task queue.getMin();synchronized(task.lock) {if (task.state TimerTask.CANCELLED) {queue.removeMin();continue; // No action required, poll queue again}currentTime System.currentTimeMillis();executionTime task.nextExecutionTime;if (taskFired (executionTime

    JDK自带Timer和TimerTask可以实现任务定时调度包括定时执行、固定间隔执行、 固定频率执行简单易用。但有三个缺点

  • 任务调度基于绝对时间而非相对时间对系统时间敏感、依赖性强。
  • 任务调度依赖同一个线程必须串行执行任务间依赖性强。
  • 若单次任务执行过程中出现异常IllegalArgumentException、IllegalStateException和NullPointerException会导致后续任务不管是否已经安排调度执行失败。
  • 转:https://www.cnblogs.com/HopkinsCybn/p/10051429.html

    【文章出处:抗攻击防御ddos http://www.558idc.com/krgf.html 复制请保留原URL】
    上一篇:poj1256
    下一篇:没有了
    网友评论