定时任务有很多种实现,网上也有很多开源的定时任务框架可以参考,但博主只简单介绍一下博主使用到的四种定时任务的实现:Timer和TimerTaks、spring、quartz、spring和quartz。话不多说,直接上代码
我们先来看看Timer的源码
public void schedule(TimerTask task, Date firstTime, long period) {
if (period <= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, firstTime.getTime(), -period);
}
task是继承了TimerTask的自定义任务,firstTime:第一次执行时间 period:执行周期
再来看看Timer的构造方法
//Timer提供了四个构造方法,以此为例
public Timer(String name, boolean isDaemon) {
thread.setName(name);
thread.setDaemon(isDaemon);
thread.start();
}
可以看到Timer是基于线程的,isDaemon是否设置为守护进程
来看看start干了什么
public synchronized void start() {
//如果线程已经运行则抛出异常
if (threadStatus != 0)
throw new IllegalThreadStateException();
//将此线程加入到线程队列
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
//然而start0并没有做什么事情,可见,start只是将线程放入线程队列
private native void start0();
然而Timer就提供了四个不同作用的方法:构造方法 、shcedule、cancel、purge
回归到核心方法schedule,我们来看看sched:
private void sched(TimerTask task, long time, long period) {
if (time < 0)
throw new IllegalArgumentException("Illegal execution time.");
if (Math.abs(period) > (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);
//如果是对首就唤醒线程,执行TimerTask
if (queue.getMin() == task)
queue.notify();
}
}
继承了TimerTask的类只需要其run方法就好
@Override
public void run() {
System.out.println("scheduleTask start :++++++++++++++++");
}
初始化这个类是就会启动任务
定义一个类方法中调用timer的schedule,然后在spring启动时初始化这个方法即可
public void executeTask() throws ParseException {
// 以每24小时执行一次
timer.schedule(
new TimerTask() {
@Override
public void run() {
System.out.println("scheduleTask start :++++++++++++++++");
}, startTime, daySpan);
}
配置文件
<bean id="scheduleTask" class="com.task.ScheduleTask" init- method="executeTask">
bean>
实现继承了TimerTask的类的run方法,将调度任务交给spring
public class ScheduleTask extends TimerTask{
@Override
public void run() {
System.out.println("scheduleTask start :++++++++++++++++");
}
}
配置文件如下:
<bean id="scheduleTask" class="com.task.ScheduleTask">
bean>
<bean id="scheduledExecutorService" class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean">
<property name="awaitTerminationSeconds" value="300"/>
<property name="continueScheduledExecutionAfterException" value="false"/>
<property name="poolSize" value="1"/>
<property name="scheduledExecutorTasks">
<list>
<ref bean="scheduledExecutorTask"/>
list>
property>
<property name="waitForTasksToCompleteOnShutdown" value="true"/>
<property name="threadPriority" value="1"/>
bean>
<bean id="scheduledExecutorTask"
class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
<property name="fixedRate" value="true"/>
<property name="period" value="1"/>
<property name="timeUnit" value="MILLISECONDS"/>
<property name="runnable" ref="scheduleTask"/>
bean>
这里看一下fixedRate的源码
protected void registerTasks(ScheduledExecutorTask[] tasks, ScheduledExecutorService executor) {
for (ScheduledExecutorTask task : tasks) {
Runnable runnable = getRunnableToSchedule(task);
if (task.isOneTimeTask()) {
executor.schedule(runnable, task.getDelay(), task.getTimeUnit());
}
else {
if (task.isFixedRate()) {
executor.scheduleAtFixedRate(runnable, task.getDelay(), task.getPeriod(), task.getTimeUnit());
}
else {
executor.scheduleWithFixedDelay(runnable, task.getDelay(), task.getPeriod(), task.getTimeUnit());
}
}
}
}
看不下去了以后再说~