一:简介

在JDK类库中Timer主要负责计划任务的功能,也就是在指定时间执行某一任务,执行时候会在主线程之外起一个单独的线程执行指定的任务。该类主要是设置任务计划,但封装的类是TimerTask类。
TimerTask是一个实现了Runnable接口的抽象类,代表一个可被执行的任务,执行任务的代码要放在其子类中(TimerTask是抽象类)。

二:Timer整体类图

TimerTask类:主要为定时任务的具体内容。
Timer类中含有3个类:Timer、TimerThread、TaskQueue。
Timer类主要是设置定时任务,配置用户期望的任务执行时间、执行次数、执行内容
TimerThread类为Thread的扩展类,会一直从TaskQueue中获取下标为1的TimerTask进行执行。并根据该TimerTask是否需要重复执行来决定是否放回到TaskQueue中。
TaskQueue中存放一些列将要执行的TimerTask,以数组的形式存放,下标约小(注:下标为0不处理,即使用的最小下标为1),则表明优先级越高。
public class Timer {//默认给线程命名:"Timer-" + serialNumber()public Timer() {this("Timer-" + serialNumber());}//指定Timer的名字public Timer(String name) {thread.setName(name);thread.start();}//isDaemon:是否为守护线程public Timer(boolean isDaemon) {this("Timer-" + serialNumber(), isDaemon);}//给定线程名字,守护线程与否public Timer(String name, boolean isDaemon) {thread.setName(name);//setDaemon是指定线程是否为守护线程,true是守护线程,当主线程退出,      守护线程退出thread.setDaemon(isDaemon);thread.start();}
}//TimerThread类 继承Thread
class TimerThread extends Thread{private void mainLoop() {......//每次执行下标为1的TimerTasktask = queue.getMin();......}
}//TaskQueue 类
class TaskQueue {//TaskQueue 中存储TimerTaskprivate TimerTask[] queue = new TimerTask[128];//返回数组中下标1的TimerTaskTimerTask getMin() {return queue[1];}
}

三:Timer常用方法

1.Timer 类void schedule(TimerTask task, Date time)方法

1.task是定时任务,time是task任务执行时间.如果time时间早于当前则立即执行,否则在time时间执行。
2.task只执行一次,且执行完Timer线程任务不结束,因为Timer不是守护线程,Timer timer = new Timer(true);
是指定Timer 为守护线程,当task执行结束后,Timer 线程会立即结束。
3.Timer 可以执行多个定时任务,TimerTask 将会按照队列的方式一个一个被执行,如果前面的任务耗时长,后面的任务执行时间将会相应的延后。
public class TimerDemo {//指定Timer为守护线程,run方法结束Timer线程会结束。private static Timer timer = new Timer(true);//TimerTask 具体的定时任务static public class MyTask extends TimerTask {@Overridepublic void run() {System.out.println("已运行,时间为:" + new Date());}}public static void main(String[] args) {//创建定时任务MyTask myTask = new MyTask();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//早于当前时间,定时任务会立即执行String dateString = "2020-06-01 09:56:00";try {Date taskDate = sdf.parse(dateString);//启动定时任务timer.schedule(myTask,taskDate);} catch (Exception e) {e.printStackTrace();}}
}
已运行,时间为:Wed Jul 01 14:48:06 CST 2020

2.Timer 类void schedule(TimerTask task, Date firstTime, long period)方法

TimerTask任务在指定 firstTime任务之后,周期性每隔period时间,无限期循环的执行某一任务。

3.TimerTask 类boolean cancel()方法

TimerTask 类boolean cancel()方法,是将自身任务从任务队列中移除。

public class TimerDemo {private static Timer timer = new Timer();static public class MyTaskA extends TimerTask {@Overridepublic void run() {//只输出一次,MyTaskA 任务将会移除System.out.println("MyTaskA已运行,时间为:" + new Date());//执行TimerTask的cancel方法,将自身任务从队列中移除this.cancel();}}static public class MyTaskB extends TimerTask {@Overridepublic void run() {//移除MyTaskA任务,MyTaskB 任务不受影响System.out.println("MyTaskB已运行,时间为:" + new Date());}}public static void main(String[] args) {MyTaskA myTaskA = new MyTaskA();MyTaskB myTaskB = new MyTaskB();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2020-07-01 15:19:00";try {Date taskDate = sdf.parse(dateString);timer.schedule(myTaskA,taskDate,2000);timer.schedule(myTaskB,taskDate,2000);} catch (Exception e) {e.printStackTrace();}}
}
MyTaskA已运行,时间为:Wed Jul 01 15:24:47 CST 2020
MyTaskB已运行,时间为:Wed Jul 01 15:24:47 CST 2020
MyTaskB已运行,时间为:Wed Jul 01 15:24:49 CST 2020
MyTaskB已运行,时间为:Wed Jul 01 15:24:51 CST 2020
MyTaskB已运行,时间为:Wed Jul 01 15:24:53 CST 2020
MyTaskB已运行,时间为:Wed Jul 01 15:24:55 CST 2020
MyTaskB已运行,时间为:Wed Jul 01 15:24:57 CST 2020
MyTaskB已运行,时间为:Wed Jul 01 15:24:59 CST 2020

4.Timer 类void cancel()方法

Timer 类void cancel()方法与TimerTask 类boolean cancel()方法将自身任务从任务队列中移除不同,它是将所有的任务都从队列中移除。

public class TimerDemo {private static Timer timer = new Timer();static public class MyTaskA extends TimerTask {@Overridepublic void run() {System.out.println("MyTaskA已运行,时间为:" + new Date());//执行Timer类的cancel方法,将Timer中所有任务从队列中移除timer.cancel();}}static public class MyTaskB extends TimerTask {@Overridepublic void run() {//MyTaskB也会被移除,因为MyTaskA与MyTaskB是队列执行,先执行MyTaskA再执行MyTaskB//MyTaskA中走了timer.cancel(),所以MyTaskB不会执行System.out.println("MyTaskB已运行,时间为:" + new Date());}}public static void main(String[] args) {MyTaskA myTaskA = new MyTaskA();MyTaskB myTaskB = new MyTaskB();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2020-07-01 15:19:00";try {Date taskDate = sdf.parse(dateString);timer.schedule(myTaskA,taskDate,2000);timer.schedule(myTaskB,taskDate,2000);} catch (Exception e) {e.printStackTrace();}}
}
MyTaskA已运行,时间为:Wed Jul 01 16:20:48 CST 2020

源码:

public void cancel() {synchronized(queue) {thread.newTasksMayBeScheduled = false;queue.clear();queue.notify();  // In case queue was already empty.}}

执行cancel需要抢占queue锁,如果抢不到,则TimerTask 任务会继续执行。

5.Timer 类 void schedule(TimerTask task, long delay)方法

该方法以schedule(TimerTask task, long delay)方法的执行时间为基准,在此时间上延迟指定的毫秒数delay后执行一次TimerTask 任务。

6.Timer 类 void schedule(TimerTask task, long delay, long period)方法

该方法以schedule(TimerTask task, long delay, long period)方法的执行时间为基准,在此时间上延迟指定的毫秒数delay后,执行TimerTask 任务,之后间隔period毫秒无限循环执行TimerTask 任务。

7.Timer 类void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)方法

TimerTask任务在指定 firstTime任务之后,周期性每隔period时间,无限期循环的执行某一任务。

四:重点:scheduleAtFixedRate(TimerTask task, Date firstTime, long period)与 schedule(TimerTask task, Date firstTime, long period)方法区别

1.相同点:两个方法都是按照顺序执行,无线程安全问题
2.任务不延时相同点:如果任务执行时间小于任务时间间隔,则第二次任务的开始时间是任务开始时间+period
3.任务延时相同点:如果任务执行时间大于任务时间间隔,导致第二次任务开始时候,上一个任务还未结束,则第二次任务的开始时间是在第一次任务结束时候立即执行。

scheduleAtFixedRate方法与schedule方法的追赶性问题

scheduleAtFixedRate方法具有追赶性!!!!如果计划执行时间早于当前时间,执行scheduleAtFixedRate方法后立即执行定时任务,根据任务间隔时间与当前时间减去计划执行时间,补上之前少执行的任务。
schedule方法不具有追赶性。!!!!

public class TimerDemo {private static Timer timer = new Timer();static public class MyTaskA extends TimerTask {@Overridepublic void run() {System.out.println("MyTaskA已运行,时间为:" + new Date());try {//任务执行时间是1sThread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("MyTaskA已结束,时间为:" + new Date());}}public static void main(String[] args) {MyTaskA myTaskA = new MyTaskA();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString = "2020-07-02 14:31:00";try {Date taskDate = sdf.parse(dateString);//3s执行一次任务timer.scheduleAtFixedRate(myTaskA,taskDate,3000);} catch (Exception e) {e.printStackTrace();}}
}
MyTaskA已运行,时间为:Thu Jul 02 14:34:38 CST 2020
MyTaskA已结束,时间为:Thu Jul 02 14:34:39 CST 2020
MyTaskA已运行,时间为:Thu Jul 02 14:34:39 CST 2020
MyTaskA已结束,时间为:Thu Jul 02 14:34:40 CST 2020
MyTaskA已运行,时间为:Thu Jul 02 14:34:40 CST 2020
MyTaskA已结束,时间为:Thu Jul 02 14:34:41 CST 2020
MyTaskA已运行,时间为:Thu Jul 02 14:34:41 CST 2020
MyTaskA已结束,时间为:Thu Jul 02 14:34:42 CST 2020
MyTaskA已运行,时间为:Thu Jul 02 14:34:42 CST 2020
MyTaskA已结束,时间为:Thu Jul 02 14:34:43 CST 2020
MyTaskA已运行,时间为:Thu Jul 02 14:34:43 CST 2020
MyTaskA已结束,时间为:Thu Jul 02 14:34:44 CST 2020
MyTaskA已运行,时间为:Thu Jul 02 14:34:44 CST 2020
MyTaskA已结束,时间为:Thu Jul 02 14:34:45 CST 2020
MyTaskA已运行,时间为:Thu Jul 02 14:34:45 CST 2020
MyTaskA已结束,时间为:Thu Jul 02 14:34:46 CST 2020
MyTaskA已运行,时间为:Thu Jul 02 14:34:46 CST 2020

由上述执行结果可知,在Thu Jul 02 14:34:38 CST 2020启动定时任务后,没有间隔3s再执行下一次任务,而是任务结束就立即执行,这是因为任务计划执行时间早于当前时间,需要将这期间没有执行的任务补上。

五: 总结

java中可以使用定时任务的功能,针对不同的定时任务可以根据不同的API进行处理,从本质来说改技术仍然属于多线程,基于多线程实现,不管用再多的框架实现定时器功能,请不要忘了这事java基础,框架实现的基础。

定时器Timer与TimerTask的使用相关推荐

  1. 【Android 异步操作】Timer 定时器 ( Timer 与 TimerTask 基本使用 | Timer 定时器常用用法 | Timer 源码分析 )

    文章目录 一.Timer 定时器基本使用 二.Timer 定时器常用用法 三.Timer 源码分析 四.Timer 部分源码注释 五.源码及资源下载 参考文档 : Timer 定时器 API 文档 T ...

  2. java timer和timertask_java定时器Timer和TimerTask详解

    目录结构: Timer和TimerTask 一个Timer调度的例子 如何终止Timer线程 关于cancle方式终止线程 反复执行一个任务 schedule VS. scheduleAtFixedR ...

  3. java定时器-Timer和TimerTask详解

    1.例子入手 package pers.growing.test;import java.util.Timer; import java.util.TimerTask;public class Mai ...

  4. android Timer与TimerTask的相关操作

    项目上面的部分操作需要使用到定时器进行周期性的控制.网络上面对于定时器的操作通常有三种实现方法. 我是通过Timer与TimerTask相结合实现的定时器功能.具体实现过程如下: 第一步,得到Time ...

  5. Java 中Timer和TimerTask 定时器和定时任务使用的例子

    转载自  Java 中Timer和TimerTask 定时器和定时任务使用的例子 这两个类使用起来非常方便,可以完成我们对定时器的绝大多数需求 Timer类是用来执行任务的类,它接受一个TimerTa ...

  6. Java的定时器Timer和定时任务TimerTask应用以及原理简析

    记录:272 场景:Java JDK自带的定时器Timer和定时任务TimerTask应用以及原理简析.在JDK工具包:java.util中可以找到源码,即java.util.Timer和java.u ...

  7. Timer和TimerTask

    Timer和TimerTask 在项目中偶然间看到通过这个方式实现的计时功能,所以想适当地进行归纳和总结 虽然说是总结,但是还是参考了下述文档: http://blog.csdn.net/ahxu/a ...

  8. Java定时器Timer

    Java定时器Timer 在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时开始执行某一个任务.Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,执行计划 ...

  9. 第5章 定时器Timer

    第5章 定时器Timer 标签: Java多线程编程 <Java多线程编程核心技术> 个人笔记 第5章 定时器Timer 定时器Timer的使用 方法scheduleTimerTask t ...

最新文章

  1. C#按关闭按钮实现最小化,按ESC才关闭的实现【含系统消息大全】
  2. python搞笑代码-python有趣代码
  3. 基础回顾(Map、==/equals()/hashcode())
  4. 为什么肯德基旁边总有一家麦当劳
  5. Android运行Socket项目时出现错误 Error: ShouldNotReachHere()
  6. 向量外积_解析几何 -向量
  7. leetcode刷题:零钱兑换
  8. 结合CKFinder,给CKEditor加上上传图片功能
  9. Python——配置环境的导出与导入
  10. softmgr主程序_为什么我电脑打开后,我的电脑打不开,控制面板一
  11. linux用管理员给用户权限,Linux普通用户获得管理员权限
  12. visio安装问题总结
  13. 动态规划经典例题详解
  14. 第七届高教杯计算机绘图,第七届”高教杯“全国大学生先进成图技术与产品信息建模创新大赛机械类计算机绘图试卷.pdf...
  15. 过流保护的几种实现方式
  16. nofollow是什么意思?nofollow标签的写法和作用
  17. 又一个程序猿的奋斗史——第五章 苦逼的宿舍条件
  18. 以太坊交易中的nonce和confirmation
  19. 微信公众平台开发(1)验证TOKEN源码
  20. 计算机算法与结构知识点,【数学】“算法初步与框图”知识点总结

热门文章

  1. window.open浏览器弹出新窗口被拦截—原因分析和解决方案
  2. Excel某列数值以固定值增长
  3. 【坑】javascript中appName总是Netscape的原因
  4. 按日期生成文件夹,并删除之前的文件夹
  5. 40隐式构造函数和隐式转换,还有explicit关键词的确切含义【C++学习笔记】
  6. php订阅号增粉,微信公众号增粉方案(10个微信公众号增粉办法)
  7. SpringBoot 配置 HTTPS 安全证书的两种方案
  8. 唯众模块化物联网技术综合实训装置的设计与实现
  9. 智慧养老解决方案-最新全套合集
  10. IntelliJ IDEA 2018.3.2的颜色代码JRA