浅谈java定时任务:TimerTask

java 定时任务TimerTask

定时任务有很多种实现,网上也有很多开源的定时任务框架可以参考,但博主只简单介绍一下博主使用到的四种定时任务的实现:Timer和TimerTaks、spring、quartz、spring和quartz。话不多说,直接上代码

Timer和TimerTask

我们先来看看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和spring

定义一个类方法中调用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和Spring

实现继承了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());
                }
            }
        }
    }

看不下去了以后再说~

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值