• Java定时任务--Timer和TimerTask


    1.程序和编程

    我们知道,计算机程序是一组计算机能识别和执行的指令,运行于电子计算机上,满足人们某种需求的信息化工具。

    简单来说程序在本质上是指令的集合,而编程从字面上来讲就是编写这些指令集合(程序),通过程序去完成某种行为。

    在日常编程中,我们难免会遇到这种情况,如何在指定的时间去做某一件事情(比如闹钟响铃)?在Java中通常使用定时任务去实现,接下来会结合源码分析Java中的定时任务。

    2.从段子开始

     上面是一个关于时间和线程的段子。当然段子毕竟是为博众人一笑,我们开发中获取时间会有更好的方式。这里要说的是,如果我们要在下一天去做某个动作(比如上面说的闹钟响铃),

    这种线程睡眠不失为一种简单的方法(虽然我们通常不建议使用这种方式,更倾向使用定时任务)。

    3.Java定时任务

     简单的说Timer中有两个核心部分:

    • TimerThread是时间线程,控制TaskQueue中TimerTask的执行;
    • TaskQueue是一个工具类,管理TimerTask数组

    而Timer暴露的主要是一系列schedule方法,去建立Timer和TimerTask的联系。我们看到Java定时任务设计中很重要的部分就是定时器和任务的分离。

    以上是简单的示例,在使用定时任务时要注意几点:

    • 一个Timer可以执行多个TimerTask,但一个TimerTask只能被一个Timer使用(这和schedule中校验TimerTask的状态有关,TimerTask的生命周期(由不同的状态确定))。
    • 通常不使用匿名类创建TimerTask抽象类的子类,建议创建单独的子类extend TimerTask。
    • 根据实际需要采用不同的schedule方法或者scheduleAtFixedRate方法执行任务。
    • 合理使用cancel和purge方法。

    4.源码浅析

    结合第3部分的简单示例,来梳理源码。

    ①创建Timer和TimerTask

    Timer的核心构造方法,调用此方法时启动,初始化创建的TimerThread线程。

     

     ②执行schedule或scheduleAtFixedRate方法

     其中核心的sched方法,主要是判断线程的状态,TimerTask的状态,然后将通过校验的TimerTask添加到TaskQueue,其后交由TimerThread管理。

    ③TimerThread原理

    时间线程TimerThread中run方法执行的mianLoop方法如上,会一直循环执行。

    a.获取TaskQueue中的第一个序列的TimerTask(通过getMin()方法获取),这里很重要,每次循环后TaskQueue序列可能会变化。

    b.然后校验TimerTask的状态,移除TaskQueue不需要执行的TimerTask

    c.对于能够执行的TimerTask,校验当前时间和执行时间, 通过taskFired标识(表示TimerTask是否就绪,可以执行),(然后处理只执行一次的,从TaskQueue中移除,按频率执行多次的重新排序,详见rescheduleMin方法)。

    d.未就绪的TimerTask将wait,而就绪(状态正常且到执行时间的TimerTask)的执行TimerTask的run方法。此时该Timer中的TimerTask执行完毕,后续的就是TimerTask线程逻辑。

    ④TaskQueue和TimerTask

    结合源码可以了解TaskQueue如何排序,以及TimerTask中不同的状态(生命周期)的意义。

    4.总结

    Java原生的定时任务包括Timer和TimerTask两部分,Timer为主,TimerTask为辅。

    Timer中由TimerThread线程控制TimerTask是否执行,Java通过这两个类完成了定时任务的基本功能。

    学习时不只是要学习其源码中内部实现,工作原理。更要关注Timer和TimerTask分离的思想,这很重要。

    后续学习Java中其他的定时任务,如Spring的定时任务,Quartz。

  • 相关阅读:
    回调函数
    BIRT实现组内跨行计算
    POJ 3616 Milking Time DP题解
    string的内存管理问题
    天津政府应急系统之GIS一张图(arcgis api for flex)解说(三)显示地图坐标系模块
    myeclipse将java项目转换成web项目,导出war包
    Spring之IOC篇章具体解释
    为RAC私有网络配置网卡Bonding
    聊聊高并发(九)实现几种自旋锁(四)
    鼠标放上去Div旋转特效代码
  • 原文地址:https://www.cnblogs.com/masting/p/11627964.html
Copyright © 2020-2023  润新知