浅谈java定时任务:TimerTask

来源:互联网 发布:筑业计价软件 编辑:程序博客网 时间:2024/04/29 14:21

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());                }            }        }    }

看不下去了以后再说~

2 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 只考上二本大学怎么办 w7电脑中病毒了怎么办 电脑中病毒了该怎么办 泰迪呼吸急促怎么办啊 狗狗呼吸急促是怎么办 狗狗着凉了呕吐怎么办 狗鼻子流黄鼻涕怎么办 刚出生婴儿睡觉不踏实怎么办 有人溺水后你该怎么办 借钱不还怎么办没欠条 私人欠货款不还怎么办 公司欠货款不还怎么办 两个人离婚一方不同意怎么办 比亚迪l3油耗高怎么办 u盘密码忘记了怎么办 主板没有m.2接口怎么办 点痣留下了疤怎么办 危险三角区长痘痘怎么办 挤了危险三角区怎么办 三角区长痘挤了怎么办 三角区发红长痘怎么办 激光祛斑碰水了怎么办 激光打痣留下坑怎么办 点痣之后留下坑怎么办 去痣留下的红印怎么办 激光点痦子留疤怎么办 激光点痣的疤痕怎么办 做完眉毛碰水了怎么办 脸上疤掉了有坑怎么办 结痂不小心抠掉怎么办 脸上肉松弛怎么办19岁 点痣留下来的疤怎么办 激光祛斑的红印怎么办 脸上疤掉了红印怎么办 痘痘发炎了红肿怎么办 脸上的斑越来越多了怎么办 点痣留下的疤痕怎么办 额头又高又大怎么办 脸太长额头太高怎么办 动车因台风停运怎么办 爸妈50了要离婚怎么办