【java】源码详解java定时任务,
分享于 点击 32355 次 点评:91
【java】源码详解java定时任务,
网上找了找,java写定时任务的方法很多,框架也有很多提供了定时任务接口,对于初学java程序员来说,还是考虑JDK里面的内容比较适合。先看原理:
JDK中,定时器任务的执行需要两个基本的类:java.util.Timer;
java.util.TimerTask;
要运行一个定时任务,最基本的步骤如下:
1、建立一个要执行的任务TimerTask。
2、创建一个Timer实例,通过Timer提供的schedule()方法,将 TimerTask加入到定时器Timer中,同时设置执行的规则即可。
当程序执行了Timer初始化代码后,Timer定时任务就会按照设置去执行。
Timer中的schedule()方法是有多种重载格式的,以适应不同的情况。该方法的格式如下:
void schedule(TimerTask task, Date time)
安排在指定的时间执行指定的任务。
void schedule(TimerTask task, Date firstTime, long period)
安排指定的任务在指定的时间开始进行重复的固定延迟执行。
void schedule(TimerTask task, long delay)
安排在指定延迟后执行指定的任务。
void schedule(TimerTask task, long delay, long period)
安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
Timer是线程安全的,此类可扩展到大量同时安排的任务(存在数千个都没有问题)。其所有构造方法都启动计时器线程。可以调用cancel() 终止此计时器,丢弃所有当前已安排的任务。purge()从此计时器的任务队列中移除所有已取消的任务。此类不提供实时保证:它使用 Object.wait(long) 方法来安排任务。
TimerTask是一个抽象类,由 Timer 安排为一次执行或重复执行的任务。它有一个抽象方法run()----计时器任务要执行的操作。因此,每个具体的任务类都必须继承TimerTask类,并且重写run()方法。另外它还有两个非抽象的方法:
boolean cancel()
取消此计时器任务。
long scheduledExecutionTime()
返回此任务最近实际 执行的安排 执行时间。
再看源码:
package nov;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
*
*
* <p>
* Title: 定时任务测试代码 /p>
*
* <p>
* Description: 示例 业务类
* </p>
*
* <p>
* Copyright: Copyright (c) 2012
* </p>
*
*
* @author dml@2012-11-29
* @version 1.0
*/
public class TimerTest extends TimerTask {
/**
* 此计时器任务要执行的操作。
*/
public void run() {
Date executeTime = new Date(this.scheduledExecutionTime());
System.out.println("本次任务执行的时间是" + executeTime);
}
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTest();
timer.schedule(task, 500L, 1000L);
}
}
本次任务执行的时间是Thu Nov 29 10:39:38 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:39 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:40 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:41 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:42 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:43 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:44 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:45 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:46 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:47 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:48 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:49 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:50 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:51 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:52 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:53 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:54 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:55 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:56 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:57 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:58 CST 2012
本次任务执行的时间是Thu Nov 29 10:39:59 CST 2012
……
分析:
上面的示例调用的方法如下:
/**
* Schedules the specified task for repeated <i>fixed-delay execution</i>,
* beginning after the specified delay. Subsequent executions take place
* at approximately regular intervals separated by the specified period.
*
* <p>In fixed-delay execution, each execution is scheduled relative to
* the actual execution time of the previous execution. If an execution
* is delayed for any reason (such as garbage collection or other
* background activity), subsequent executions will be delayed as well.
* In the long run, the frequency of execution will generally be slightly
* lower than the reciprocal of the specified period (assuming the system
* clock underlying <tt>Object.wait(long)</tt> is accurate).
*
* <p>Fixed-delay execution is appropriate for recurring activities
* that require "smoothness." In other words, it is appropriate for
* activities where it is more important to keep the frequency accurate
* in the short run than in the long run. This includes most animation
* tasks, such as blinking a cursor at regular intervals. It also includes
* tasks wherein regular activity is performed in response to human
* input, such as automatically repeating a character as long as a key
* is held down.
*
* @param task task to be scheduled.
* @param delay delay in milliseconds before task is to be executed.
* @param period time in milliseconds between successive task executions.
* @throws IllegalArgumentException if <tt>delay</tt> is negative, or
* <tt>delay + System.currentTimeMillis()</tt> is negative.
* @throws IllegalStateException if task was already scheduled or
* cancelled, timer was cancelled, or timer thread terminated.
*/
public void schedule(TimerTask task, long delay, long period) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
if (period <= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, System.currentTimeMillis()+delay, -period);
}
三个参数:任务 延时时间 连续周期
时间设置合理后调用sched方法:
/**
* 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 <tt>time()</tt> is negative.
* @throws IllegalStateException if task was already scheduled or
* cancelled, timer was cancelled, or timer thread terminated.
*/
private void sched(TimerTask task, long time, long period) {
if (time < 0)
throw new IllegalArgumentException("Illegal execution time.");
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();
}
}
synchronized修饰,保证线程安全...Timer类还有很多其他的方法,有空再一个个试试。
p.s.经常看JDK里面的代码,能帮助养成良好的代码注释风格,这点很重要。
dml@2012.11.29
相关文章
- 暂无相关文章
用户点评